[PHP-CVS] com php-src: Fixed bug #62987 (Assigning to ArrayObject[null][something] overrides all undefined variables): NEWS ext/spl/spl_array.c ext/spl/tests/bug62978.phpt

2012-09-01 Thread Xinchen Hui
Commit:67d7d03f00cb3185a4d5958ab7a4b063fc33405c
Author:Xinchen Hui larue...@php.net Sat, 1 Sep 2012 14:17:39 +0800
Parents:   5dc2cef370885c552c20f3ff44bccd402850de9e
Branches:  PHP-5.3

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=67d7d03f00cb3185a4d5958ab7a4b063fc33405c

Log:
Fixed bug #62987 (Assigning to ArrayObject[null][something] overrides all 
undefined variables)

The get_zval_ptr_ptr of spl_array handler should act as same as the vm's

Bugs:
https://bugs.php.net/62987

Changed paths:
  M  NEWS
  M  ext/spl/spl_array.c
  A  ext/spl/tests/bug62978.phpt


Diff:
diff --git a/NEWS b/NEWS
index a6e05be..ae82821 100644
--- a/NEWS
+++ b/NEWS
@@ -45,6 +45,8 @@ PHP   
 NEWS
   . Fixed bug (segfault due to retval is not initialized). (Laruence)
 
 - SPL:
+  . Bug #62987 (Assigning to ArrayObject[null][something] overrides all 
+undefined variables). (Laruence)
   . Fixed bug #62904 (Crash when cloning an object which inherits 
SplFixedArray)
 (Laruence)
   . Fixed bug #62616 (ArrayIterator::count() from IteratorIterator instance
diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index 80ca5be..11540de 100755
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -312,38 +312,41 @@ static zval **spl_array_get_dimension_ptr_ptr(int 
check_inherited, zval *object,
long index;
HashTable *ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
 
-/*  We cannot get the pointer pointer so we don't allow it here for now
-   if (check_inherited  intern-fptr_offset_get) {
-   return zend_call_method_with_1_params(object, 
Z_OBJCE_P(object), intern-fptr_offset_get, offsetGet, NULL, offset);
-   }*/
-
if (!offset) {
return EG(uninitialized_zval_ptr);
}

if ((type == BP_VAR_W || type == BP_VAR_RW)  (ht-nApplyCount  0)) {
zend_error(E_WARNING, Modification of ArrayObject during 
sorting is prohibited);
-   return EG(uninitialized_zval_ptr);;
+   return EG(error_zval_ptr);;
}
 
switch(Z_TYPE_P(offset)) {
+   case IS_NULL:
+   Z_STRVAL_P(offset) = ;
+   Z_STRLEN_P(offset) = 0;
case IS_STRING:
if (zend_symtable_find(ht, Z_STRVAL_P(offset), 
Z_STRLEN_P(offset)+1, (void **) retval) == FAILURE) {
-   if (type == BP_VAR_W || type == BP_VAR_RW) {
-   zval *value;
-   ALLOC_INIT_ZVAL(value);
-   zend_symtable_update(ht, Z_STRVAL_P(offset), 
Z_STRLEN_P(offset)+1, (void**)value, sizeof(void*), NULL);
-   zend_symtable_find(ht, Z_STRVAL_P(offset), 
Z_STRLEN_P(offset)+1, (void **) retval);
-   return retval;
-   } else {
-   zend_error(E_NOTICE, Undefined index:  %s, 
Z_STRVAL_P(offset));
-   return EG(uninitialized_zval_ptr);
+   switch (type) {
+   case BP_VAR_R:
+   zend_error(E_NOTICE, Undefined index:  
%s, Z_STRVAL_P(offset));
+   case BP_VAR_UNSET:
+   case BP_VAR_IS:
+   retval = EG(uninitialized_zval_ptr);
+   break;
+   case BP_VAR_RW:
+   zend_error(E_NOTICE,Undefined index:  
%s, Z_STRVAL_P(offset));
+   case BP_VAR_W: {
+   zval *value;
+   ALLOC_INIT_ZVAL(value);
+   zend_symtable_update(ht, 
Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void**)value, sizeof(void*), (void 
**)retval);
+   }
}
-   } else {
-   return retval;
}
-   case IS_DOUBLE:
+   return retval;
case IS_RESOURCE:
+   zend_error(E_STRICT, Resource ID#%ld used as offset, casting 
to integer (%ld), Z_LVAL_P(offset), Z_LVAL_P(offset));
+   case IS_DOUBLE:
case IS_BOOL: 
case IS_LONG: 
if (offset-type == IS_DOUBLE) {
@@ -352,23 +355,27 @@ static zval **spl_array_get_dimension_ptr_ptr(int 
check_inherited, zval *object,
index = Z_LVAL_P(offset);
}
if (zend_hash_index_find(ht, index, (void **) retval) == 
FAILURE) {
-   if (type == BP_VAR_W || type == BP_VAR_RW) {
-   zval *value;
-   ALLOC_INIT_ZVAL(value);
-   zend_hash_index_update(ht, index, 
(void**)value, sizeof(void*), NULL);
-   

[PHP-CVS] com php-src: Merge branch 'PHP-5.3' into PHP-5.4: NEWS ext/spl/spl_array.c

2012-09-01 Thread Xinchen Hui
Commit:863e7e0acbe284d5c7738fa9c601023ad5773d3f
Author:Xinchen Hui larue...@php.net Sat, 1 Sep 2012 14:27:09 +0800
Parents:   e658a91b3d826ea4104b17f3a6123c1e9f3aee86 
67d7d03f00cb3185a4d5958ab7a4b063fc33405c
Branches:  PHP-5.4

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=863e7e0acbe284d5c7738fa9c601023ad5773d3f

Log:
Merge branch 'PHP-5.3' into PHP-5.4

Conflicts:
ext/spl/spl_array.c

Changed paths:
  MM  NEWS
  MM  ext/spl/spl_array.c


Diff:
diff --cc NEWS
index d88aa18,ae82821..62e2038
--- a/NEWS
+++ b/NEWS
@@@ -60,121 -43,53 +60,123 @@@ PH
  
  - Session:
. Fixed bug (segfault due to retval is not initialized). (Laruence)
 +  . Fixed bug (segfault due to PS(mod_user_implemented) not be reseted 
 +when close handler call exit). (Laruence)
  
  - SPL:
+   . Bug #62987 (Assigning to ArrayObject[null][something] overrides all 
+ undefined variables). (Laruence)
. Fixed bug #62904 (Crash when cloning an object which inherits 
SplFixedArray)
  (Laruence)
 +  . Implemented FR #62840 (Add sort flag to ArrayObject::ksort). (Laruence)
 +
 +- Standard:
 +  . Fixed bug #62836 (Seg fault or broken object references on unserialize()).
 +(Laruence)
 +
 +- FPM:
 +  . Merged PR 121 by minitux to add support for slow request counting on PHP
 +FPM status page. (Lars)
 +
 +16 Aug 2012, PHP 5.4.6
 +
 +- CLI Server:
 +  . Implemented FR #62700 (have the console output 'Listening on 
 +http://localhost:8000'). (pascal.chev...@free.fr)
 +
 +- Core:
 +  . Fixed bug #62661 (Interactive php-cli crashes if include() is used in
 +auto_prepend_file). (Laruence)
 +  . Fixed bug #62653: (unset($array[$float]) causes a crash). (Nikita Popov,
 +Laruence)
 +  . Fixed bug #62565 (Crashes due non-initialized internal properties_table).
 +(Felipe)
 +  . Fixed bug #60194 (--with-zend-multibyte and --enable-debug reports LEAK
 +with run-test.php). (Laruence)
 +
 +- CURL:
 +  . Fixed bug #62499 (curl_setopt($ch, CURLOPT_COOKIEFILE, ) returns false).
 +(r.hampartsum...@gmail.com, Laruence)
 +
 +- DateTime:
 +  . Fixed Bug #62500 (Segfault in DateInterval class when extended). 
(Laruence)
 +  
 +- Fileinfo:
 +  . Fixed bug #61964 (finfo_open with directory causes invalid free). 
 +(reeze@gmail.com)
 +
 +- Intl:
 +  . Fixed bug #62564 (Extending MessageFormatter and adding property causes 
 +crash). (Felipe)
 +
 +- MySQLnd:
 +  . Fixed bug #62594 (segfault in mysqlnd_res_meta::set_mode). (Laruence)
 +
 +- readline:
 +  . Fixed bug #62612 (readline extension compilation fails with
 +sapi/cli/cli.h: No such file). (Johannes)
 +
 +- Reflection:
 +  . Implemented FR #61602 (Allow access to name of constant used as default 
 +value). (reeze@gmail.com)
 +  
 +- SimpleXML:
 +  . Implemented FR #55218 Get namespaces from current node. (Lonny)
 +
 +- SPL:
. Fixed bug #62616 (ArrayIterator::count() from IteratorIterator instance
  gives Segmentation fault). (Laruence, Gustavo)
 +  . Fixed bug #61527 (ArrayIterator gives misleading notice on next() when 
 +moved to the end). (reeze@gmail.com)
  
 -- Enchant:
 -  . Fixed bug #62838 (enchant_dict_quick_check() destroys zval, but fails to 
 -  initialize it). (Tony, Mateusz Goik).
 +- Streams:
 +  . Fixed bug #62597 (segfault in php_stream_wrapper_log_error with ZTS 
build).
 +(Laruence)
  
 -19 Jul 2012, PHP 5.3.15
 +- Zlib:
 +  . Fixed bug #55544 (ob_gzhandler always conflicts with
 +zlib.output_compression). (Laruence)
  
 -- Zend Engine:
 -  . Fixed bug #51094 (parse_ini_file() with INI_SCANNER_RAW cuts a value that
 -includes a semi-colon). (Pierrick)
 -
 -- COM:
 -  . Fixed bug #62146 com_dotnet cannot be built shared. (Johannes)
 +19 Jul 2012, PHP 5.4.5
  
  - Core:
 -  . Fixed potential overflow in _php_stream_scandir, CVE-2012-2688. (Jason 
 -Powell, Stas)
 -  . Fixed bug #62432 (ReflectionMethod random corrupt memory on high
 -concurrent). (Johannes)
. Fixed bug #62443 (Crypt SHA256/512 Segfaults With Malformed 
  Salt). (Anthony Ferrara)
 +  . Fixed bug #62432 (ReflectionMethod random corrupt memory on high
 +concurrent). (Johannes)
 +  . Fixed bug #62373 (serialize() generates wrong reference to the object).
 +(Moriyoshi)
 +  . Fixed bug #62357 (compile failure: (S) Arguments missing for built-in
 +function __memcmp). (Laruence)
 +  . Fixed bug #61998 (Using traits with method aliases appears to result in
 +crash during execution). (Dmitry)
 +  . Fixed bug #51094 (parse_ini_file() with INI_SCANNER_RAW cuts a value that
 +includes a semi-colon). (Pierrick)
 +  . Fixed potential overflow in _php_stream_scandir (CVE-2012-2688). 
 +(Jason Powell, Stas)
  
 -- Fileinfo:
 -  . Fixed magic file regex support. (Felipe)
 +- EXIF:
 +  . Fixed information leak in ext exif (discovered by Martin Noga, 
 +Matthew j00ru Jurczyk, Gynvael Coldwind)
  
  - FPM:
 -  . Fixed bug #61045 (fpm don't send error log to fastcgi 

[PHP-CVS] com php-src: Remove extra blank in notice message, should act as same as vm: ext/spl/spl_array.c ext/spl/spl_iterators.c ext/spl/tests/arrayObject___construct_basic2.phpt ext/spl/tests/array

2012-09-01 Thread Xinchen Hui
Commit:f3108b5f818b2757d2e518f37d3927e83858ae4f
Author:Xinchen Hui larue...@php.net Sat, 1 Sep 2012 14:37:45 +0800
Parents:   863e7e0acbe284d5c7738fa9c601023ad5773d3f
Branches:  PHP-5.4

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=f3108b5f818b2757d2e518f37d3927e83858ae4f

Log:
Remove extra blank in notice message, should act as same as vm

Changed paths:
  M  ext/spl/spl_array.c
  M  ext/spl/spl_iterators.c
  M  ext/spl/tests/arrayObject___construct_basic2.phpt
  M  ext/spl/tests/arrayObject___construct_basic3.phpt
  M  ext/spl/tests/arrayObject___construct_basic4.phpt
  M  ext/spl/tests/arrayObject___construct_basic5.phpt
  M  ext/spl/tests/arrayObject_magicMethods1.phpt
  M  ext/spl/tests/arrayObject_magicMethods3.phpt
  M  ext/spl/tests/arrayObject_magicMethods4.phpt
  M  ext/spl/tests/arrayObject_magicMethods6.phpt
  M  ext/spl/tests/arrayObject_setFlags_basic1.phpt
  M  ext/spl/tests/array_001.phpt
  M  ext/spl/tests/array_010.phpt
  M  ext/spl/tests/bug45622.phpt
  M  ext/spl/tests/bug45622b.phpt
  M  ext/spl/tests/bug54323.phpt
  M  ext/spl/tests/bug62978.phpt
  M  ext/spl/tests/iterator_044.phpt

diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index 0b3b5a3..3c6b41e 100755
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -323,13 +323,13 @@ static zval **spl_array_get_dimension_ptr_ptr(int 
check_inherited, zval *object,
if (zend_symtable_find(ht, Z_STRVAL_P(offset), 
Z_STRLEN_P(offset)+1, (void **) retval) == FAILURE) {
switch (type) {
case BP_VAR_R:
-   zend_error(E_NOTICE, Undefined index:  
%s, Z_STRVAL_P(offset));
+   zend_error(E_NOTICE, Undefined index: 
%s, Z_STRVAL_P(offset));
case BP_VAR_UNSET:
case BP_VAR_IS:
retval = EG(uninitialized_zval_ptr);
break;
case BP_VAR_RW:
-   zend_error(E_NOTICE,Undefined index:  
%s, Z_STRVAL_P(offset));
+   zend_error(E_NOTICE,Undefined index: 
%s, Z_STRVAL_P(offset));
case BP_VAR_W: {
zval *value;
ALLOC_INIT_ZVAL(value);
@@ -351,13 +351,13 @@ static zval **spl_array_get_dimension_ptr_ptr(int 
check_inherited, zval *object,
if (zend_hash_index_find(ht, index, (void **) retval) == 
FAILURE) {
switch (type) {
case BP_VAR_R:
-   zend_error(E_NOTICE, Undefined offset: 
 %ld, index);
+   zend_error(E_NOTICE, Undefined offset: 
%ld, index);
case BP_VAR_UNSET:
case BP_VAR_IS:
retval = EG(uninitialized_zval_ptr);
break;
case BP_VAR_RW:
-   zend_error(E_NOTICE, Undefined offset: 
 %ld, index);
+   zend_error(E_NOTICE, Undefined offset: 
%ld, index);
case BP_VAR_W: {
zval *value;
ALLOC_INIT_ZVAL(value);
@@ -520,11 +520,11 @@ static void spl_array_unset_dimension_ex(int 
check_inherited, zval *object, zval
}
if (ht == EG(symbol_table)) {
if (zend_delete_global_variable(Z_STRVAL_P(offset), 
Z_STRLEN_P(offset) TSRMLS_CC)) {
-   zend_error(E_NOTICE,Undefined index:  %s, 
Z_STRVAL_P(offset));
+   zend_error(E_NOTICE,Undefined index: %s, 
Z_STRVAL_P(offset));
}
} else {
if (zend_symtable_del(ht, Z_STRVAL_P(offset), 
Z_STRLEN_P(offset)+1) == FAILURE) {
-   zend_error(E_NOTICE,Undefined index:  %s, 
Z_STRVAL_P(offset));
+   zend_error(E_NOTICE,Undefined index: %s, 
Z_STRVAL_P(offset));
} else {
spl_array_object *obj = intern;
 
@@ -570,7 +570,7 @@ static void spl_array_unset_dimension_ex(int 
check_inherited, zval *object, zval
return;
}
if (zend_hash_index_del(ht, index) == FAILURE) {
-   zend_error(E_NOTICE,Undefined offset:  %ld, 
Z_LVAL_P(offset));
+   zend_error(E_NOTICE,Undefined offset: %ld, 
Z_LVAL_P(offset));
}
break;
default:
diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c
index e5dc030..098d7dc 100755
--- 

[PHP-CVS] com php-src: Merge branch 'PHP-5.4': ext/spl/spl_iterators.c

2012-09-01 Thread Xinchen Hui
Commit:7b5960b08577700275468b396e6f962e0b70
Author:Xinchen Hui larue...@php.net Sat, 1 Sep 2012 14:38:33 +0800
Parents:   59e34bad32cecd823577f43756776d6d6936e93e 
f3108b5f818b2757d2e518f37d3927e83858ae4f
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=7b5960b08577700275468b396e6f962e0b70

Log:
Merge branch 'PHP-5.4'

Changed paths:
  MM  ext/spl/spl_iterators.c


Diff:



--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-CVS] com php-src: Fixed bug #62987 (Assigning to ArrayObject[null][something] overrides all undefined variables): NEWS ext/spl/spl_array.c ext/spl/tests/bug62978.phpt

2012-09-01 Thread Laruence
Hi Rms:

this bug is a critical one.  please notice this fix. :)

thanks

On Sat, Sep 1, 2012 at 2:21 PM, Xinchen Hui larue...@php.net wrote:
 Commit:67d7d03f00cb3185a4d5958ab7a4b063fc33405c
 Author:Xinchen Hui larue...@php.net Sat, 1 Sep 2012 14:17:39 
 +0800
 Parents:   5dc2cef370885c552c20f3ff44bccd402850de9e
 Branches:  PHP-5.3

 Link:   
 http://git.php.net/?p=php-src.git;a=commitdiff;h=67d7d03f00cb3185a4d5958ab7a4b063fc33405c

 Log:
 Fixed bug #62987 (Assigning to ArrayObject[null][something] overrides all 
 undefined variables)

 The get_zval_ptr_ptr of spl_array handler should act as same as the vm's

 Bugs:
 https://bugs.php.net/62987

 Changed paths:
   M  NEWS
   M  ext/spl/spl_array.c
   A  ext/spl/tests/bug62978.phpt


 Diff:
 diff --git a/NEWS b/NEWS
 index a6e05be..ae82821 100644
 --- a/NEWS
 +++ b/NEWS
 @@ -45,6 +45,8 @@ PHP 
NEWS
. Fixed bug (segfault due to retval is not initialized). (Laruence)

  - SPL:
 +  . Bug #62987 (Assigning to ArrayObject[null][something] overrides all
 +undefined variables). (Laruence)
. Fixed bug #62904 (Crash when cloning an object which inherits 
 SplFixedArray)
  (Laruence)
. Fixed bug #62616 (ArrayIterator::count() from IteratorIterator instance
 diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
 index 80ca5be..11540de 100755
 --- a/ext/spl/spl_array.c
 +++ b/ext/spl/spl_array.c
 @@ -312,38 +312,41 @@ static zval **spl_array_get_dimension_ptr_ptr(int 
 check_inherited, zval *object,
 long index;
 HashTable *ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);

 -/*  We cannot get the pointer pointer so we don't allow it here for now
 -   if (check_inherited  intern-fptr_offset_get) {
 -   return zend_call_method_with_1_params(object, 
 Z_OBJCE_P(object), intern-fptr_offset_get, offsetGet, NULL, offset);
 -   }*/
 -
 if (!offset) {
 return EG(uninitialized_zval_ptr);
 }

 if ((type == BP_VAR_W || type == BP_VAR_RW)  (ht-nApplyCount  0)) 
 {
 zend_error(E_WARNING, Modification of ArrayObject during 
 sorting is prohibited);
 -   return EG(uninitialized_zval_ptr);;
 +   return EG(error_zval_ptr);;
 }

 switch(Z_TYPE_P(offset)) {
 +   case IS_NULL:
 +   Z_STRVAL_P(offset) = ;
 +   Z_STRLEN_P(offset) = 0;
 case IS_STRING:
 if (zend_symtable_find(ht, Z_STRVAL_P(offset), 
 Z_STRLEN_P(offset)+1, (void **) retval) == FAILURE) {
 -   if (type == BP_VAR_W || type == BP_VAR_RW) {
 -   zval *value;
 -   ALLOC_INIT_ZVAL(value);
 -   zend_symtable_update(ht, Z_STRVAL_P(offset), 
 Z_STRLEN_P(offset)+1, (void**)value, sizeof(void*), NULL);
 -   zend_symtable_find(ht, Z_STRVAL_P(offset), 
 Z_STRLEN_P(offset)+1, (void **) retval);
 -   return retval;
 -   } else {
 -   zend_error(E_NOTICE, Undefined index:  %s, 
 Z_STRVAL_P(offset));
 -   return EG(uninitialized_zval_ptr);
 +   switch (type) {
 +   case BP_VAR_R:
 +   zend_error(E_NOTICE, Undefined 
 index:  %s, Z_STRVAL_P(offset));
 +   case BP_VAR_UNSET:
 +   case BP_VAR_IS:
 +   retval = EG(uninitialized_zval_ptr);
 +   break;
 +   case BP_VAR_RW:
 +   zend_error(E_NOTICE,Undefined index: 
  %s, Z_STRVAL_P(offset));
 +   case BP_VAR_W: {
 +   zval *value;
 +   ALLOC_INIT_ZVAL(value);
 +   zend_symtable_update(ht, 
 Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void**)value, sizeof(void*), 
 (void **)retval);
 +   }
 }
 -   } else {
 -   return retval;
 }
 -   case IS_DOUBLE:
 +   return retval;
 case IS_RESOURCE:
 +   zend_error(E_STRICT, Resource ID#%ld used as offset, casting 
 to integer (%ld), Z_LVAL_P(offset), Z_LVAL_P(offset));
 +   case IS_DOUBLE:
 case IS_BOOL:
 case IS_LONG:
 if (offset-type == IS_DOUBLE) {
 @@ -352,23 +355,27 @@ static zval **spl_array_get_dimension_ptr_ptr(int 
 check_inherited, zval *object,
 index = Z_LVAL_P(offset);
 }
 if (zend_hash_index_find(ht, index, (void **) retval) == 
 FAILURE) {
 -   if (type == BP_VAR_W || type == 

[PHP-CVS] com php-src: Make sure that exception is thrown on rewind() after closing too: Zend/tests/generators/generator_rewind.phpt Zend/zend_generators.c

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:cc07038fa9b2a59893c52fb0c515a1fb03e56d5c
Author:Nikita Popov ni...@php.net Wed, 29 Aug 2012 20:31:34 +0200
Parents:   d60e3c6ef53986e82178bb657ad907edc16d2c34
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=cc07038fa9b2a59893c52fb0c515a1fb03e56d5c

Log:
Make sure that exception is thrown on rewind() after closing too

Changed paths:
  M  Zend/tests/generators/generator_rewind.phpt
  M  Zend/zend_generators.c


Diff:
diff --git a/Zend/tests/generators/generator_rewind.phpt 
b/Zend/tests/generators/generator_rewind.phpt
index 3224f6a..af885ef 100644
--- a/Zend/tests/generators/generator_rewind.phpt
+++ b/Zend/tests/generators/generator_rewind.phpt
@@ -21,6 +21,14 @@ try {
 echo \n, $e, \n\n;
 }
 
+$gen = gen();
+foreach ($gen as $v) { }
+try {
+foreach ($gen as $v) { }
+} catch (Exception $e) {
+echo \n, $e, \n\n;
+}
+
 function gen2() {
 echo in generator\n;
 
@@ -40,4 +48,12 @@ Stack trace:
 #0 %s(%d): Generator-rewind()
 #1 {main}
 
+before yield
+after yield
+
+exception 'Exception' with message 'Cannot rewind a generator that was already 
run' in %s:%d
+Stack trace:
+#0 %s(%d): unknown()
+#1 {main}
+
 in generator
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 03294f7..0eb17d0 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -500,7 +500,7 @@ void zend_generator_resume(zend_generator *generator 
TSRMLS_DC) /* {{{ */
 
 static void zend_generator_ensure_initialized(zend_generator *generator 
TSRMLS_DC) /* {{{ */
 {
-   if (!generator-value) {
+   if (generator-execute_data  !generator-value) {
zend_generator_resume(generator TSRMLS_CC);
generator-flags |= ZEND_GENERATOR_AT_FIRST_YIELD;
}


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Fix segfault when traversing a by-ref generator twice: Zend/tests/generators/errors/non_ref_generator_iterated_by_ref_error.phpt Zend/tests/generators/generator_rewind.phpt Zend

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:bef79588d543db996d092191ac498751a1cc161f
Author:Nikita Popov ni...@php.net Wed, 29 Aug 2012 20:46:56 +0200
Parents:   cc07038fa9b2a59893c52fb0c515a1fb03e56d5c
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=bef79588d543db996d092191ac498751a1cc161f

Log:
Fix segfault when traversing a by-ref generator twice

If you try to traverse an already closed generator an exception will now be
thrown.

Furthermore this changes the error for traversing a by-val generator by-ref
from an E_ERROR to an Exception.

Changed paths:
  M  Zend/tests/generators/errors/non_ref_generator_iterated_by_ref_error.phpt
  M  Zend/tests/generators/generator_rewind.phpt
  M  Zend/zend_generators.c


Diff:
diff --git 
a/Zend/tests/generators/errors/non_ref_generator_iterated_by_ref_error.phpt 
b/Zend/tests/generators/errors/non_ref_generator_iterated_by_ref_error.phpt
index 9c618d2..de5b22f 100644
--- a/Zend/tests/generators/errors/non_ref_generator_iterated_by_ref_error.phpt
+++ b/Zend/tests/generators/errors/non_ref_generator_iterated_by_ref_error.phpt
@@ -10,4 +10,9 @@ foreach ($gen as $value) { }
 
 ?
 --EXPECTF--
-Fatal error: You can only iterate a generator by-reference if it declared that 
it yields by-reference in %s on line %d
+Fatal error: Uncaught exception 'Exception' with message 'You can only iterate 
a generator by-reference if it declared that it yields by-reference' in %s:%d
+Stack trace:
+#0 %s(%d): unknown()
+#1 {main}
+  thrown in %s on line %d
+
diff --git a/Zend/tests/generators/generator_rewind.phpt 
b/Zend/tests/generators/generator_rewind.phpt
index af885ef..c4b5bbb 100644
--- a/Zend/tests/generators/generator_rewind.phpt
+++ b/Zend/tests/generators/generator_rewind.phpt
@@ -21,21 +21,27 @@ try {
 echo \n, $e, \n\n;
 }
 
-$gen = gen();
+function gen2() {
+$foo = 'bar';
+yield $foo;
+yield $foo;
+}
+
+$gen = gen2();
 foreach ($gen as $v) { }
 try {
 foreach ($gen as $v) { }
 } catch (Exception $e) {
-echo \n, $e, \n\n;
+echo $e, \n\n;
 }
 
-function gen2() {
+function gen3() {
 echo in generator\n;
 
 if (false) yield;
 }
 
-$gen = gen2();
+$gen = gen3();
 $gen-rewind();
 
 ?
@@ -48,10 +54,7 @@ Stack trace:
 #0 %s(%d): Generator-rewind()
 #1 {main}
 
-before yield
-after yield
-
-exception 'Exception' with message 'Cannot rewind a generator that was already 
run' in %s:%d
+exception 'Exception' with message 'Cannot traverse an already closed 
generator' in %s:%d
 Stack trace:
 #0 %s(%d): unknown()
 #1 {main}
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 0eb17d0..60fa8b6 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -766,8 +766,14 @@ zend_object_iterator 
*zend_generator_get_iterator(zend_class_entry *ce, zval *ob
 
generator = (zend_generator *) zend_object_store_get_object(object 
TSRMLS_CC);
 
+   if (!generator-execute_data) {
+   zend_throw_exception(NULL, Cannot traverse an already closed 
generator, 0 TSRMLS_CC);
+   return NULL;
+   }
+
if (by_ref  !(generator-execute_data-op_array-fn_flags  
ZEND_ACC_RETURN_REFERENCE)) {
-   zend_error(E_ERROR, You can only iterate a generator 
by-reference if it declared that it yields by-reference);
+   zend_throw_exception(NULL, You can only iterate a generator 
by-reference if it declared that it yields by-reference, 0 TSRMLS_CC);
+   return NULL;
}
 
iterator = emalloc(sizeof(zend_generator_iterator));


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Merge remote-tracking branch 'php-src/master' into addGeneratorsSupport: Zend/zend_compile.c Zend/zend_compile.h Zend/zend_language_parser.y Zend/zend_vm_def.h Zend/zend_vm_exec

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:d60e3c6ef53986e82178bb657ad907edc16d2c34
Author:Nikita Popov ni...@php.net Sat, 25 Aug 2012 20:07:01 +0200
Parents:   bd70d155885fdc087afba912c1b290615b864e2f 
35951d4be0bd27c85519995a95429bd0d0a76a00
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=d60e3c6ef53986e82178bb657ad907edc16d2c34

Log:
Merge remote-tracking branch 'php-src/master' into addGeneratorsSupport

Conflicts:
Zend/zend_language_parser.y
Zend/zend_vm_execute.skl

Changed paths:
  MM  Zend/zend_compile.c
  MM  Zend/zend_compile.h
  MM  Zend/zend_language_parser.y
  MM  Zend/zend_vm_def.h
  MM  Zend/zend_vm_execute.h
  MM  Zend/zend_vm_execute.skl


Diff:
diff --cc Zend/zend_vm_def.h
index 1016679,92c5fcf..ffd81b0
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@@ -3049,20 -3053,12 +3051,20 @@@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF
  
FREE_OP1_IF_VAR();
  
-   if (EX(op_array)-has_finally_block) {
-   ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, 
type, ZEND_RETURN_BY_REF);
+   if (EXPECTED(!EX(op_array)-has_finally_block)) {
+   ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
}
-   ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+   ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, type, 
ZEND_RETURN_BY_REF);
  }
  
 +ZEND_VM_HANDLER(161, ZEND_GENERATOR_RETURN, ANY, ANY)
 +{
 +  if (EX(op_array)-has_finally_block) {
 +  ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, 
type, ZEND_RETURN);
 +  }
 +  ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
 +}
 +
  ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
  {
USE_OPLINE
diff --cc Zend/zend_vm_execute.h
index a643967,1e0b2b5..b0e05b1
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@@ -409,26 -400,6 +409,26 @@@ zend_execute_data *zend_create_execute_
EX(function_state).function = (zend_function *) op_array;
EX(function_state).arguments = NULL;
  
 +  return execute_data;
 +}
 +
 +ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS_DC)
 +{
 +  DCL_OPLINE
- 
-   zend_bool original_in_execution = EG(in_execution);
++  zend_bool original_in_execution;
 +
 +
 +
 +  if (EG(exception)) {
 +  return;
 +  }
 +
++  original_in_execution = EG(in_execution);
 +  EG(in_execution) = 1;
 +
 +  LOAD_REGS();
 +  LOAD_OPLINE();
 +
while (1) {
int ret;
  #ifdef ZEND_WIN32
diff --cc Zend/zend_vm_execute.skl
index 25b3d71,0c5e8a3..58e5631
--- a/Zend/zend_vm_execute.skl
+++ b/Zend/zend_vm_execute.skl
@@@ -70,28 -63,6 +70,28 @@@ zend_execute_data *zend_create_execute_
EX(function_state).function = (zend_function *) op_array;
EX(function_state).arguments = NULL;
  
 +  return execute_data;
 +}
 +
 +ZEND_API void {%EXECUTOR_NAME%}_ex(zend_execute_data *execute_data TSRMLS_DC)
 +{
 +  DCL_OPLINE
- 
-   zend_bool original_in_execution = EG(in_execution);
++  zend_bool original_in_execution;
 +
 +  {%HELPER_VARS%}
 +
 +  {%INTERNAL_LABELS%}
 +
 +  if (EG(exception)) {
 +  return;
 +  }
 +
++  original_in_execution = EG(in_execution);
 +  EG(in_execution) = 1;
 +
 +  LOAD_REGS();
 +  LOAD_OPLINE();
 +
while (1) {
  {%ZEND_VM_CONTINUE_LABEL%}
  #ifdef ZEND_WIN32


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Add dedicated opcode for returns from a generator: Zend/zend_opcode.c Zend/zend_vm_def.h Zend/zend_vm_execute.h Zend/zend_vm_opcodes.h

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:68c1e1cfe95b026086cacf40a005ea8f399e9595
Author:Nikita Popov ni...@php.net Fri, 24 Aug 2012 13:51:39 +0200
Parents:   6517ed021520a608a18da4653cb9c6b414121f6f
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=68c1e1cfe95b026086cacf40a005ea8f399e9595

Log:
Add dedicated opcode for returns from a generator

Generators don't have a return value, so it doesn't make sense to have
a shared implementation here.

Changed paths:
  M  Zend/zend_opcode.c
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h
  M  Zend/zend_vm_opcodes.h


Diff:
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index 0f39b8a..5c4b20f 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -586,9 +586,8 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
CG(zend_lineno) = 
opline-lineno;
zend_error(E_COMPILE_ERROR, 
Generators cannot return values using \return\);
}
-   if (opline-opcode == 
ZEND_RETURN_BY_REF) {
-   opline-opcode = ZEND_RETURN;
-   }
+
+   opline-opcode = ZEND_GENERATOR_RETURN;
}
break;
}
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 975a2a7..216cd59 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2931,17 +2931,6 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
zval *retval_ptr;
zend_free_op free_op1;
 
-   if (EX(op_array)-fn_flags  ZEND_ACC_GENERATOR) {
-   /* The generator object is stored in return_value_ptr_ptr */
-   zend_generator *generator = (zend_generator *) 
EG(return_value_ptr_ptr);
-
-   /* Close the generator to free up resources */
-   zend_generator_close(generator, 1 TSRMLS_CC);
-
-   /* Pass execution back to handling code */
-   ZEND_VM_RETURN();
-   }
-
SAVE_OPLINE();
retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
 
@@ -3066,6 +3055,14 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, 
CONST|TMP|VAR|CV, ANY)
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
 }
 
+ZEND_VM_HANDLER(162, ZEND_GENERATOR_RETURN, ANY, ANY)
+{
+   if (EX(op_array)-has_finally_block) {
+   ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, 
type, ZEND_RETURN);
+   }
+   ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+}
+
 ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
 {
USE_OPLINE
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 402442f..ebc0fb9 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -885,6 +885,14 @@ static int ZEND_FASTCALL  
ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER
return 
zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  
ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+   if (EX(op_array)-has_finally_block) {
+   return zend_finally_handler_leaving_SPEC(ZEND_RETURN, 
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+   }
+   return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+}
+
 static int ZEND_FASTCALL  ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
USE_OPLINE
@@ -2443,17 +2451,6 @@ static int ZEND_FASTCALL  
ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval *retval_ptr;
 
 
-   if (EX(op_array)-fn_flags  ZEND_ACC_GENERATOR) {
-   /* The generator object is stored in return_value_ptr_ptr */
-   zend_generator *generator = (zend_generator *) 
EG(return_value_ptr_ptr);
-
-   /* Close the generator to free up resources */
-   zend_generator_close(generator, 1 TSRMLS_CC);
-
-   /* Pass execution back to handling code */
-   ZEND_VM_RETURN();
-   }
-
SAVE_OPLINE();
retval_ptr = opline-op1.zv;
 
@@ -7760,17 +7757,6 @@ static int ZEND_FASTCALL  
ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *retval_ptr;
zend_free_op free_op1;
 
-   if (EX(op_array)-fn_flags  ZEND_ACC_GENERATOR) {
-   /* The generator object is stored in return_value_ptr_ptr */
-   zend_generator *generator = (zend_generator *) 
EG(return_value_ptr_ptr);
-
-   /* Close the generator to free up resources */
-   zend_generator_close(generator, 1 TSRMLS_CC);
-
-   /* Pass execution back to handling code */
-   ZEND_VM_RETURN();
-   }
-
SAVE_OPLINE();
retval_ptr = _get_zval_ptr_tmp(opline-op1.var, EX_Ts(), free_op1 
TSRMLS_CC);
 
@@ -12982,17 +12968,6 @@ static int ZEND_FASTCALL  
ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 

[PHP-CVS] com php-src: Finally with return now works in generators too: Zend/tests/generators/finally_with_return.phpt

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:7cdf6367a51a54fce8676aeb6fd32bf91b00f84b
Author:Nikita Popov ni...@php.net Fri, 24 Aug 2012 13:52:16 +0200
Parents:   68c1e1cfe95b026086cacf40a005ea8f399e9595
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=7cdf6367a51a54fce8676aeb6fd32bf91b00f84b

Log:
Finally with return now works in generators too

Changed paths:
  A  Zend/tests/generators/finally_with_return.phpt


Diff:
diff --git a/Zend/tests/generators/finally_with_return.phpt 
b/Zend/tests/generators/finally_with_return.phpt
new file mode 100644
index 000..b26a49f
--- /dev/null
+++ b/Zend/tests/generators/finally_with_return.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Use of finally in generator with return
+--FILE--
+?php
+
+function gen() {
+try {
+try {
+echo before return\n;
+return;
+echo after return\n;
+} finally {
+echo before return in inner finally\n;
+return;
+echo after return in inner finally\n;
+}
+} finally {
+echo outer finally run\n;
+}
+
+echo code after finally\n;
+
+yield; // force generator
+}
+
+$gen = gen();
+$gen-rewind(); // force run
+
+?
+--EXPECTF--
+before return
+before return in inner finally
+outer finally run


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Merge remote-tracking branch 'php-src/master' into addGeneratorsSupport: Zend/zend_compile.c Zend/zend_compile.h Zend/zend_opcode.c Zend/zend_vm_def.h Zend/zend_vm_execute.h

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:6517ed021520a608a18da4653cb9c6b414121f6f
Author:Nikita Popov ni...@php.net Fri, 24 Aug 2012 13:29:40 +0200
Parents:   f45a0f31c8354947c0e2b9ea44a63fc0a2c23a01 
071580ea1f450513dba2dbf585a9498614f855e7
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=6517ed021520a608a18da4653cb9c6b414121f6f

Log:
Merge remote-tracking branch 'php-src/master' into addGeneratorsSupport

Conflicts:
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

Changed paths:
  MM  Zend/zend_compile.c
  MM  Zend/zend_compile.h
  MM  Zend/zend_opcode.c
  MM  Zend/zend_vm_def.h
  MM  Zend/zend_vm_execute.h

diff --cc Zend/zend_vm_def.h
index f8955c5,ce1674e..975a2a7
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@@ -1840,291 -1840,296 +1840,294 @@@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VA
ZEND_VM_NEXT_OPCODE();
  }
  
- ZEND_VM_HANDLER(42, ZEND_JMP, ANY, ANY)
+ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
  {
-   USE_OPLINE
- 
- #if DEBUG_ZEND=2
-   printf(Jumping to %d\n, opline-op1.opline_num);
- #endif
-   ZEND_VM_SET_OPCODE(opline-op1.jmp_addr);
-   ZEND_VM_CONTINUE(); /* CHECK_ME */
- }
+   zend_bool nested;
+   zend_op_array *op_array = EX(op_array);
  
- ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMP|VAR|CV, ANY)
- {
-   USE_OPLINE
-   zend_free_op free_op1;
-   zval *val;
-   int ret;
++  /* Generators go throw a different cleanup process */
++  if (EX(op_array)-fn_flags  ZEND_ACC_GENERATOR) {
++  /* The generator object is stored in return_value_ptr_ptr */
++  zend_generator *generator = (zend_generator *) 
EG(return_value_ptr_ptr);
 +
-   SAVE_OPLINE();
-   val = GET_OP1_ZVAL_PTR(BP_VAR_R);
++  /* Close the generator to free up resources */
++  zend_generator_close(generator, 1 TSRMLS_CC);
 +
-   if (OP1_TYPE == IS_TMP_VAR  EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
-   ret = Z_LVAL_P(val);
-   } else {
-   ret = i_zend_is_true(val);
-   FREE_OP1();
-   if (UNEXPECTED(EG(exception) != NULL)) {
-   HANDLE_EXCEPTION();
-   }
-   }
-   if (!ret) {
- #if DEBUG_ZEND=2
-   printf(Conditional jmp to %d\n, opline-op2.opline_num);
- #endif
-   ZEND_VM_SET_OPCODE(opline-op2.jmp_addr);
-   ZEND_VM_CONTINUE();
++  /* Pass execution back to handling code */
++  ZEND_VM_RETURN();
 +  }
 +
-   ZEND_VM_NEXT_OPCODE();
- }
+   EG(current_execute_data) = EX(prev_execute_data);
+   EG(opline_ptr) = NULL;
+   if (!EG(active_symbol_table)) {
 -  zval ***cv = EX_CVs();
 -  zval ***end = cv + op_array-last_var;
 -  while (cv != end) {
 -  if (*cv) {
 -  zval_ptr_dtor(*cv);
 -  }
 -  cv++;
 -  }
++  zend_free_compiled_variables(EX_CVs(), op_array-last_var);
+   }
  
- ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMP|VAR|CV, ANY)
- {
-   USE_OPLINE
-   zend_free_op free_op1;
-   zval *val;
-   int ret;
+   if ((op_array-fn_flags  ZEND_ACC_CLOSURE)  op_array-prototype) {
+   zval_ptr_dtor((zval**)op_array-prototype);
+   }
  
-   SAVE_OPLINE();
-   val = GET_OP1_ZVAL_PTR(BP_VAR_R);
+   nested = EX(nested);
  
-   if (OP1_TYPE == IS_TMP_VAR  EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
-   ret = Z_LVAL_P(val);
 -  zend_vm_stack_free(execute_data TSRMLS_CC);
++  /* For generators the execute_data is stored on the heap, for everything
++   * else it is stored on the VM stack. */
++  if (op_array-fn_flags  ZEND_ACC_GENERATOR) {
++  efree(execute_data);
 +  } else {
-   ret = i_zend_is_true(val);
-   FREE_OP1();
-   if (UNEXPECTED(EG(exception) != NULL)) {
-   HANDLE_EXCEPTION();
-   }
++  zend_vm_stack_free(execute_data TSRMLS_CC);
 +  }
-   if (ret) {
- #if DEBUG_ZEND=2
-   printf(Conditional jmp to %d\n, opline-op2.opline_num);
- #endif
-   ZEND_VM_SET_OPCODE(opline-op2.jmp_addr);
-   ZEND_VM_CONTINUE();
+ 
+   if (nested) {
+   execute_data = EG(current_execute_data);
}
+   if (nested) {
+   USE_OPLINE
  
-   ZEND_VM_NEXT_OPCODE();
- }
+   LOAD_REGS();
+   LOAD_OPLINE();
+   if (UNEXPECTED(opline-opcode == ZEND_INCLUDE_OR_EVAL)) {
  
- ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMP|VAR|CV, ANY)
- {
-   USE_OPLINE
-   zend_free_op free_op1;
-   zval *val;
-   int retval;
+   EX(function_state).function = (zend_function *) 
EX(op_array);
+   EX(function_state).arguments = NULL;
+   EX(object) = EX(current_object);
  
-   

[PHP-CVS] com php-src: Disallow serialization and unserialization: Zend/tests/generators/errors/serialize_unserialize_error.phpt Zend/zend_generators.c

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:f45a0f31c8354947c0e2b9ea44a63fc0a2c23a01
Author:Nikita Popov ni...@php.net Mon, 20 Aug 2012 16:01:16 +0200
Parents:   1823b16fa15894f72fc01724766289dbecf5a62a
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=f45a0f31c8354947c0e2b9ea44a63fc0a2c23a01

Log:
Disallow serialization and unserialization

Changed paths:
  A  Zend/tests/generators/errors/serialize_unserialize_error.phpt
  M  Zend/zend_generators.c


Diff:
diff --git a/Zend/tests/generators/errors/serialize_unserialize_error.phpt 
b/Zend/tests/generators/errors/serialize_unserialize_error.phpt
new file mode 100644
index 000..a8470b0
--- /dev/null
+++ b/Zend/tests/generators/errors/serialize_unserialize_error.phpt
@@ -0,0 +1,46 @@
+--TEST--
+Generators can't be serialized or unserialized
+--FILE--
+?php
+
+function gen() { yield; }
+
+$gen = gen();
+
+try {
+serialize($gen);
+} catch (Exception $e) {
+echo $e, \n\n;
+}
+
+try {
+var_dump(unserialize('O:9:Generator:0:{}'));
+} catch (Exception $e) {
+echo $e, \n\n;
+}
+
+try {
+var_dump(unserialize('C:9:Generator:0:{}'));
+} catch (Exception $e) {
+echo $e;
+}
+
+?
+--EXPECTF--
+exception 'Exception' with message 'Serialization of 'Generator' is not 
allowed' in %s:%d
+Stack trace:
+#0 %s(%d): serialize(Object(Generator))
+#1 {main}
+
+exception 'Exception' with message 'Unserialization of 'Generator' is not 
allowed' in %s:%d
+Stack trace:
+#0 [internal function]: Generator-__wakeup()
+#1 %s(%d): unserialize('O:9:Generator...')
+#2 {main}
+
+
+Notice: unserialize(): Error at offset 19 of 20 bytes in %s on line %d
+exception 'Exception' with message 'Unserialization of 'Generator' is not 
allowed' in %s:%d
+Stack trace:
+#0 %s(%d): unserialize('C:9:Generator...')
+#1 {main}
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 41c6dfc..b4d8932 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -590,6 +590,23 @@ ZEND_METHOD(Generator, send)
}
 }
 
+
+/* {{{ proto void Generator::__wakeup
+ * Throws an Exception as generators can't be serialized */
+ZEND_METHOD(Generator, __wakeup)
+{
+   /* Just specifying the zend_class_unserialize_deny handler is not 
enough,
+* because it is only invoked for C unserialization. For O the error has
+* to be thrown in __wakeup. */
+
+   if (zend_parse_parameters_none() == FAILURE) {
+   return;
+   }
+
+   zend_throw_exception(NULL, Unserialization of 'Generator' is not 
allowed, 0 TSRMLS_CC);
+}
+/* }}} */
+
 /* get_iterator implementation */
 
 typedef struct _zend_generator_iterator {
@@ -712,12 +729,13 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_generator_send, 0, 0, 1)
 ZEND_END_ARG_INFO()
 
 static const zend_function_entry generator_functions[] = {
-   ZEND_ME(Generator, rewind,  arginfo_generator_void, ZEND_ACC_PUBLIC)
-   ZEND_ME(Generator, valid,   arginfo_generator_void, ZEND_ACC_PUBLIC)
-   ZEND_ME(Generator, current, arginfo_generator_void, ZEND_ACC_PUBLIC)
-   ZEND_ME(Generator, key, arginfo_generator_void, ZEND_ACC_PUBLIC)
-   ZEND_ME(Generator, next,arginfo_generator_void, ZEND_ACC_PUBLIC)
-   ZEND_ME(Generator, send,arginfo_generator_send, ZEND_ACC_PUBLIC)
+   ZEND_ME(Generator, rewind,   arginfo_generator_void, ZEND_ACC_PUBLIC)
+   ZEND_ME(Generator, valid,arginfo_generator_void, ZEND_ACC_PUBLIC)
+   ZEND_ME(Generator, current,  arginfo_generator_void, ZEND_ACC_PUBLIC)
+   ZEND_ME(Generator, key,  arginfo_generator_void, ZEND_ACC_PUBLIC)
+   ZEND_ME(Generator, next, arginfo_generator_void, ZEND_ACC_PUBLIC)
+   ZEND_ME(Generator, send, arginfo_generator_send, ZEND_ACC_PUBLIC)
+   ZEND_ME(Generator, __wakeup, arginfo_generator_void, ZEND_ACC_PUBLIC)
ZEND_FE_END
 };
 
@@ -729,6 +747,8 @@ void zend_register_generator_ce(TSRMLS_D) /* {{{ */
zend_ce_generator = zend_register_internal_class(ce TSRMLS_CC);
zend_ce_generator-ce_flags |= ZEND_ACC_FINAL_CLASS;
zend_ce_generator-create_object = zend_generator_create;
+   zend_ce_generator-serialize = zend_class_serialize_deny;
+   zend_ce_generator-unserialize = zend_class_unserialize_deny;
 
/* get_iterator has to be assigned *after* implementing the inferface */
zend_class_implements(zend_ce_generator TSRMLS_CC, 1, zend_ce_iterator);


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Drop Generator::close() method: Zend/tests/generators/clone_with_foreach.phpt Zend/tests/generators/clone_with_stack.phpt Zend/tests/generators/clone_with_symbol_table.phpt Zend

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:05f10480c556ebe52bbef52cb2da5a0aca8ee070
Author:Nikita Popov ni...@php.net Mon, 20 Aug 2012 12:53:18 +0200
Parents:   7195a5b3768e519b8f50d131a8c7041a0b57959e
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=05f10480c556ebe52bbef52cb2da5a0aca8ee070

Log:
Drop Generator::close() method

Changed paths:
  M  Zend/tests/generators/clone_with_foreach.phpt
  M  Zend/tests/generators/clone_with_stack.phpt
  M  Zend/tests/generators/clone_with_symbol_table.phpt
  M  Zend/tests/generators/clone_with_this.phpt
  D  Zend/tests/generators/close_inside_generator.phpt
  D  Zend/tests/generators/generator_close.phpt
  M  Zend/tests/generators/yield_during_method_call.phpt
  M  Zend/zend_generators.c
  M  Zend/zend_generators.h


Diff:
diff --git a/Zend/tests/generators/clone_with_foreach.phpt 
b/Zend/tests/generators/clone_with_foreach.phpt
index b887338..b05ed07 100644
--- a/Zend/tests/generators/clone_with_foreach.phpt
+++ b/Zend/tests/generators/clone_with_foreach.phpt
@@ -20,7 +20,7 @@ $g2-next();
 var_dump($g1-current());
 var_dump($g2-current());
 
-$g1-close();
+unset($g1);
 $g2-next();
 var_dump($g2-current());
 
diff --git a/Zend/tests/generators/clone_with_stack.phpt 
b/Zend/tests/generators/clone_with_stack.phpt
index 673c0e5..5a8e6d8 100644
--- a/Zend/tests/generators/clone_with_stack.phpt
+++ b/Zend/tests/generators/clone_with_stack.phpt
@@ -10,7 +10,7 @@ function gen() {
 $g1 = gen();
 $g1-rewind();
 $g2 = clone $g1;
-$g1-close();
+unset($g1);
 $g2-send(10);
 
 ?
diff --git a/Zend/tests/generators/clone_with_symbol_table.phpt 
b/Zend/tests/generators/clone_with_symbol_table.phpt
index 0d1bd4e..e1fefeb 100644
--- a/Zend/tests/generators/clone_with_symbol_table.phpt
+++ b/Zend/tests/generators/clone_with_symbol_table.phpt
@@ -19,7 +19,7 @@ function gen() {
 $g1 = gen();
 $g1-rewind();
 $g2 = clone $g1;
-$g1-close();
+unset($g1);
 $g2-next();
 
 ?
diff --git a/Zend/tests/generators/clone_with_this.phpt 
b/Zend/tests/generators/clone_with_this.phpt
index 66efd02..b242d85 100644
--- a/Zend/tests/generators/clone_with_this.phpt
+++ b/Zend/tests/generators/clone_with_this.phpt
@@ -16,7 +16,7 @@ class Test {
 $g1 = (new Test)-gen();
 $g1-rewind(); // goto yield
 $g2 = clone $g1;
-$g1-close();
+unset($g1);
 $g2-next();
 
 ?
diff --git a/Zend/tests/generators/close_inside_generator.phpt 
b/Zend/tests/generators/close_inside_generator.phpt
deleted file mode 100644
index 1df64bf..000
--- a/Zend/tests/generators/close_inside_generator.phpt
+++ /dev/null
@@ -1,22 +0,0 @@
---TEST--
-Calling close() during the exectution of the generator
---FILE--
-?php
-
-function gen() {
-/* Pass the generator object itself in */
-$gen = yield;
-
-/* Close generator while it is currently running */
-$gen-close();
-
-   echo Still running;
-}
-
-$gen = gen();
-$gen-send($gen);
-
-?
---EXPECTF--
-Warning: A generator cannot be closed while it is running in %s on line %d
-Still running
diff --git a/Zend/tests/generators/generator_close.phpt 
b/Zend/tests/generators/generator_close.phpt
deleted file mode 100644
index 3dec285..000
--- a/Zend/tests/generators/generator_close.phpt
+++ /dev/null
@@ -1,32 +0,0 @@
---TEST--
-Generator can be closed by calling -close()
---FILE--
-?php
-
-function allNumbers() {
-for ($i = 0; true; ++$i) {
-yield $i;
-}
-}
-
-$numbers = allNumbers();
-
-foreach ($numbers as $n) {
-var_dump($n);
-if ($n == 9) {
-$numbers-close();
-}
-}
-
-?
---EXPECT--
-int(0)
-int(1)
-int(2)
-int(3)
-int(4)
-int(5)
-int(6)
-int(7)
-int(8)
-int(9)
diff --git a/Zend/tests/generators/yield_during_method_call.phpt 
b/Zend/tests/generators/yield_during_method_call.phpt
index e8859ac..5fbe84f 100644
--- a/Zend/tests/generators/yield_during_method_call.phpt
+++ b/Zend/tests/generators/yield_during_method_call.phpt
@@ -20,13 +20,13 @@ $gen-send('foo');
 // test resource cleanup
 $gen = gen();
 $gen-rewind();
-$gen-close();
+unset($gen);
 
 // test cloning
 $g1 = gen();
 $g1-rewind();
 $g2 = clone $g1;
-$g1-close();
+unset($g1);
 $g2-send('bar');
 
 ?
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 716b0a7..41c6dfc 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -301,8 +301,6 @@ static zend_object_value 
zend_generator_create(zend_class_entry *class_type TSRM
/* The key will be incremented on first use, so it'll start at 0 */
generator-largest_used_integer_key = -1;
 
-   generator-is_currently_running = 0;
-
zend_object_std_init(generator-std, class_type TSRMLS_CC);
 
object.handle = zend_objects_store_put(generator, NULL,
@@ -391,8 +389,6 @@ static void zend_generator_resume(zend_generator *generator 
TSRMLS_DC) /* {{{ */
zend_class_entry *original_scope = EG(scope);
zend_class_entry *original_called_scope = EG(called_scope);
 
-   zend_bool original_is_currently_running = 
generator-is_currently_running;

[PHP-CVS] com php-src: Support trivial finally in generators (no yield, no return): Zend/zend_vm_def.h Zend/zend_vm_execute.h

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:ae716939eb500f962336d37b96069cb7452c25df
Author:Nikita Popov ni...@php.net Mon, 13 Aug 2012 17:17:18 +0200
Parents:   f4ce3646285fbdd3354ca86ae67857b6ee8f7e3a
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=ae716939eb500f962336d37b96069cb7452c25df

Log:
Support trivial finally in generators (no yield, no return)

The finally clause is now properly run when an exception is thrown in the
try-block. It is not yet run on `return` and also not run when the generator
is claused within a try block.

I'll add those two things as soon as laruence refactored the finally code.

Changed paths:
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h


Diff:
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 83ae5c5..49ee314 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2513,6 +2513,18 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
zend_bool nested;
zend_op_array *op_array = EX(op_array);
 
+   /* Generators go throw a different cleanup process */
+   if (EX(op_array)-fn_flags  ZEND_ACC_GENERATOR) {
+   /* The generator object is stored in return_value_ptr_ptr */
+   zend_generator *generator = (zend_generator *) 
EG(return_value_ptr_ptr);
+
+   /* Close the generator to free up resources */
+   zend_generator_close(generator, 1 TSRMLS_CC);
+
+   /* Pass execution back to handling code */
+   ZEND_VM_RETURN();
+   }
+
EG(current_execute_data) = EX(prev_execute_data);
EG(opline_ptr) = NULL;
if (!EG(active_symbol_table)) {
@@ -5213,18 +5225,6 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
 ZEND_VM_SET_OPCODE(EX(op_array)-opcodes[finally_op_num]);
 ZEND_VM_CONTINUE();
 } else {
-   /* For generators skip the leave handler and return directly */
-   if (EX(op_array)-fn_flags  ZEND_ACC_GENERATOR) {
-   /* The generator object is stored in 
return_value_ptr_ptr */
-   zend_generator *generator = (zend_generator *) 
EG(return_value_ptr_ptr);
-
-   /* Close the generator to free up resources */
-   zend_generator_close(generator, 1 TSRMLS_CC);
-
-   /* Pass execution back to handling code */
-   ZEND_VM_RETURN();
-   }
-
 ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
 }
 }
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 495b520..94c2a7c 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -496,6 +496,18 @@ static int ZEND_FASTCALL 
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
zend_bool nested;
zend_op_array *op_array = EX(op_array);
 
+   /* Generators go throw a different cleanup process */
+   if (EX(op_array)-fn_flags  ZEND_ACC_GENERATOR) {
+   /* The generator object is stored in return_value_ptr_ptr */
+   zend_generator *generator = (zend_generator *) 
EG(return_value_ptr_ptr);
+
+   /* Close the generator to free up resources */
+   zend_generator_close(generator, 1 TSRMLS_CC);
+
+   /* Pass execution back to handling code */
+   ZEND_VM_RETURN();
+   }
+
EG(current_execute_data) = EX(prev_execute_data);
EG(opline_ptr) = NULL;
if (!EG(active_symbol_table)) {
@@ -1177,18 +1189,6 @@ static int ZEND_FASTCALL  
ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
 ZEND_VM_SET_OPCODE(EX(op_array)-opcodes[finally_op_num]);
 ZEND_VM_CONTINUE();
 } else {
-   /* For generators skip the leave handler and return directly */
-   if (EX(op_array)-fn_flags  ZEND_ACC_GENERATOR) {
-   /* The generator object is stored in 
return_value_ptr_ptr */
-   zend_generator *generator = (zend_generator *) 
EG(return_value_ptr_ptr);
-
-   /* Close the generator to free up resources */
-   zend_generator_close(generator, 1 TSRMLS_CC);
-
-   /* Pass execution back to handling code */
-   ZEND_VM_RETURN();
-   }
-
 return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 }


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Fix implementation of Iterator interface: Zend/tests/generators/generator_in_multipleiterator.phpt Zend/zend_generators.c

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:268740d9848d435054ce73a8cfe36b2b732cd1f7
Author:Nikita Popov ni...@php.net Thu, 26 Jul 2012 17:07:24 +0200
Parents:   99f93dd9a846e3d615ec61c734aca2e7ee256600
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=268740d9848d435054ce73a8cfe36b2b732cd1f7

Log:
Fix implementation of Iterator interface

It looks like you have to implement the Iterator interface *before*
assigning get_iterator. Otherwise the structure for user iterators isn't
correctly zeroed out.

Additionaly I'm setting class_entry-iterator_funcs.funcs now. Not sure if
this is strictly necessary, but better safe than sorry ;)

Changed paths:
  A  Zend/tests/generators/generator_in_multipleiterator.phpt
  M  Zend/zend_generators.c


Diff:
diff --git a/Zend/tests/generators/generator_in_multipleiterator.phpt 
b/Zend/tests/generators/generator_in_multipleiterator.phpt
new file mode 100644
index 000..611dbc9
--- /dev/null
+++ b/Zend/tests/generators/generator_in_multipleiterator.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Generators work properly in MultipleIterator
+--FILE--
+?php
+
+function gen1() {
+yield 'a';
+yield 'aa';
+}
+
+function gen2() {
+yield 'b';
+yield 'bb';
+}
+
+$it = new MultipleIterator;
+$it-attachIterator(gen1());
+$it-attachIterator(gen2());
+
+foreach ($it as $values) {
+var_dump($values);
+}
+
+?
+--EXPECT--
+array(2) {
+  [0]=
+  string(1) a
+  [1]=
+  string(1) b
+}
+array(2) {
+  [0]=
+  string(2) aa
+  [1]=
+  string(2) bb
+}
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index d7ffb30..716b0a7 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -759,9 +759,11 @@ void zend_register_generator_ce(TSRMLS_D) /* {{{ */
zend_ce_generator = zend_register_internal_class(ce TSRMLS_CC);
zend_ce_generator-ce_flags |= ZEND_ACC_FINAL_CLASS;
zend_ce_generator-create_object = zend_generator_create;
-   zend_ce_generator-get_iterator = zend_generator_get_iterator;
 
+   /* get_iterator has to be assigned *after* implementing the inferface */
zend_class_implements(zend_ce_generator TSRMLS_CC, 1, zend_ce_iterator);
+   zend_ce_generator-get_iterator = zend_generator_get_iterator;
+   zend_ce_generator-iterator_funcs.funcs = 
zend_generator_iterator_functions;
 
memcpy(zend_generator_handlers, zend_get_std_object_handlers(), 
sizeof(zend_object_handlers));
zend_generator_handlers.get_constructor = 
zend_generator_get_constructor;


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Throw error also for return occuring before yield: Zend/tests/generators/errors/generator_cannot_return_before_yield_error.phpt Zend/tests/generators/errors/generator_cannot_ret

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:134089372b94de2e3e8c2a1aba4cbc415c803d67
Author:Nikita Popov ni...@php.net Sun, 22 Jul 2012 20:11:09 +0200
Parents:   94b2ccae9ce95c4c71bb8db8ce75dcdf26df7d7a
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=134089372b94de2e3e8c2a1aba4cbc415c803d67

Log:
Throw error also for return occuring before yield

Previously only an error was thrown when return occured after yield. Also
returns before the first yield would fail for by-ref generators.

Now the error message is handled in pass_two, so all returns are checked.

Changed paths:
  A  
Zend/tests/generators/errors/generator_cannot_return_before_yield_error.phpt
  M  Zend/tests/generators/errors/generator_cannot_return_error.phpt
  M  Zend/zend_compile.c
  M  Zend/zend_opcode.c


Diff:
diff --git 
a/Zend/tests/generators/errors/generator_cannot_return_before_yield_error.phpt 
b/Zend/tests/generators/errors/generator_cannot_return_before_yield_error.phpt
new file mode 100644
index 000..ad618d2
--- /dev/null
+++ 
b/Zend/tests/generators/errors/generator_cannot_return_before_yield_error.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Generators cannot return values (even before yield)
+--FILE--
+?php
+
+function gen() {
+return $foo;
+yield;
+}
+
+?
+--EXPECTF--
+Fatal error: Generators cannot return values using return in %s on line 4
diff --git a/Zend/tests/generators/errors/generator_cannot_return_error.phpt 
b/Zend/tests/generators/errors/generator_cannot_return_error.phpt
index 9a46bff..5114906 100644
--- a/Zend/tests/generators/errors/generator_cannot_return_error.phpt
+++ b/Zend/tests/generators/errors/generator_cannot_return_error.phpt
@@ -10,4 +10,4 @@ function gen() {
 
 ?
 --EXPECTF--
-Fatal error: Generators cannot return values using return in %s on line %d
+Fatal error: Generators cannot return values using return in %s on line 5
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index f0648a2..483ff30 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2611,14 +2611,9 @@ void zend_do_return(znode *expr, int do_end_vparse 
TSRMLS_DC) /* {{{ */
 {
zend_op *opline;
int start_op_number, end_op_number;
+   zend_bool returns_reference = (CG(active_op_array)-fn_flags  
ZEND_ACC_RETURN_REFERENCE) != 0;
 
-   /* For generators the  modifier applies to the yielded values, not the
-* return value. */
-   zend_bool returns_reference = (CG(active_op_array)-fn_flags  
ZEND_ACC_RETURN_REFERENCE)  !(CG(active_op_array)-fn_flags  
ZEND_ACC_GENERATOR);
-
-   if ((CG(active_op_array)-fn_flags  ZEND_ACC_GENERATOR)  expr != 
NULL) {
-   zend_error(E_COMPILE_ERROR, Generators cannot return values 
using \return\);
-   }
+   /* The error for use of return inside a generator is thrown in 
pass_two. */
 
if (do_end_vparse) {
if (returns_reference  
!zend_is_function_or_method_call(expr)) {
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index 65fa851..0042c37 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -532,6 +532,18 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
case ZEND_JMP_SET_VAR:
opline-op2.jmp_addr = 
op_array-opcodes[opline-op2.opline_num];
break;
+   case ZEND_RETURN:
+   case ZEND_RETURN_BY_REF:
+   if (op_array-fn_flags  ZEND_ACC_GENERATOR) {
+   if (opline-op1_type != IS_CONST || 
Z_TYPE_P(opline-op1.zv) != IS_NULL) {
+   CG(zend_lineno) = 
opline-lineno;
+   zend_error(E_COMPILE_ERROR, 
Generators cannot return values using \return\);
+   }
+   if (opline-opcode == 
ZEND_RETURN_BY_REF) {
+   opline-opcode = ZEND_RETURN;
+   }
+   }
+   break;
}
ZEND_VM_SET_OPCODE_HANDLER(opline);
opline++;


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Add T_YIELD in tokenizer_data.c: ext/tokenizer/tests/token_get_all_variation11.phpt ext/tokenizer/tests/token_get_all_variation13.phpt ext/tokenizer/tests/token_get_all_variatio

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:99f93dd9a846e3d615ec61c734aca2e7ee256600
Author:Nikita Popov ni...@php.net Sun, 22 Jul 2012 20:19:07 +0200
Parents:   134089372b94de2e3e8c2a1aba4cbc415c803d67
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=99f93dd9a846e3d615ec61c734aca2e7ee256600

Log:
Add T_YIELD in tokenizer_data.c

Also had to fix up some tokenizer tests that were affected by the token
number changes.

Changed paths:
  M  ext/tokenizer/tests/token_get_all_variation11.phpt
  M  ext/tokenizer/tests/token_get_all_variation13.phpt
  M  ext/tokenizer/tests/token_get_all_variation17.phpt
  M  ext/tokenizer/tests/token_get_all_variation4.phpt
  M  ext/tokenizer/tests/token_get_all_variation5.phpt
  M  ext/tokenizer/tests/token_get_all_variation6.phpt
  M  ext/tokenizer/tests/token_get_all_variation8.phpt
  M  ext/tokenizer/tokenizer_data.c


Diff:
diff --git a/ext/tokenizer/tests/token_get_all_variation11.phpt 
b/ext/tokenizer/tests/token_get_all_variation11.phpt
index ecc8617..98d8996 100644
--- a/ext/tokenizer/tests/token_get_all_variation11.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation11.phpt
@@ -130,7 +130,7 @@ array(49) {
   [6]=
   array(3) {
 [0]=
-int(283)
+int(%d)
 [1]=
 string(2) ==
 [2]=
@@ -273,7 +273,7 @@ array(49) {
   [27]=
   array(3) {
 [0]=
-int(283)
+int(%d)
 [1]=
 string(2) ==
 [2]=
diff --git a/ext/tokenizer/tests/token_get_all_variation13.phpt 
b/ext/tokenizer/tests/token_get_all_variation13.phpt
index 9b2f3bc..6f85492 100644
--- a/ext/tokenizer/tests/token_get_all_variation13.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation13.phpt
@@ -1005,7 +1005,7 @@ array(145) {
   [122]=
   array(3) {
 [0]=
-int(288)
+int(%d)
 [1]=
 string(10) instanceof
 [2]=
diff --git a/ext/tokenizer/tests/token_get_all_variation17.phpt 
b/ext/tokenizer/tests/token_get_all_variation17.phpt
index dccc4c9..f71444b 100644
--- a/ext/tokenizer/tests/token_get_all_variation17.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation17.phpt
@@ -145,7 +145,7 @@ array(81) {
   [14]=
   array(3) {
 [0]=
-int(283)
+int(%d)
 [1]=
 string(2) ==
 [2]=
diff --git a/ext/tokenizer/tests/token_get_all_variation4.phpt 
b/ext/tokenizer/tests/token_get_all_variation4.phpt
index 45e6f8a..6bc111e 100644
--- a/ext/tokenizer/tests/token_get_all_variation4.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation4.phpt
@@ -339,7 +339,7 @@ array(89) {
   [38]=
   array(3) {
 [0]=
-int(279)
+int(%d)
 [1]=
 string(2) 
 [2]=
@@ -518,7 +518,7 @@ array(89) {
   [60]=
   array(3) {
 [0]=
-int(278)
+int(%d)
 [1]=
 string(2) ||
 [2]=
diff --git a/ext/tokenizer/tests/token_get_all_variation5.phpt 
b/ext/tokenizer/tests/token_get_all_variation5.phpt
index 0068f28..681fb48 100644
--- a/ext/tokenizer/tests/token_get_all_variation5.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation5.phpt
@@ -181,7 +181,7 @@ array(94) {
   [18]=
   array(3) {
 [0]=
-int(277)
+int(%d)
 [1]=
 string(2) +=
 [2]=
@@ -238,7 +238,7 @@ array(94) {
   [25]=
   array(3) {
 [0]=
-int(276)
+int(%d)
 [1]=
 string(2) -=
 [2]=
@@ -295,7 +295,7 @@ array(94) {
   [32]=
   array(3) {
 [0]=
-int(275)
+int(%d)
 [1]=
 string(2) *=
 [2]=
@@ -352,7 +352,7 @@ array(94) {
   [39]=
   array(3) {
 [0]=
-int(274)
+int(%d)
 [1]=
 string(2) /=
 [2]=
@@ -409,7 +409,7 @@ array(94) {
   [46]=
   array(3) {
 [0]=
-int(272)
+int(%d)
 [1]=
 string(2) %=
 [2]=
@@ -466,7 +466,7 @@ array(94) {
   [53]=
   array(3) {
 [0]=
-int(271)
+int(%d)
 [1]=
 string(2) =
 [2]=
@@ -523,7 +523,7 @@ array(94) {
   [60]=
   array(3) {
 [0]=
-int(270)
+int(%d)
 [1]=
 string(2) |=
 [2]=
@@ -580,7 +580,7 @@ array(94) {
   [67]=
   array(3) {
 [0]=
-int(269)
+int(%d)
 [1]=
 string(2) ^=
 [2]=
@@ -637,7 +637,7 @@ array(94) {
   [74]=
   array(3) {
 [0]=
-int(267)
+int(%d)
 [1]=
 string(3) =
 [2]=
@@ -694,7 +694,7 @@ array(94) {
   [81]=
   array(3) {
 [0]=
-int(268)
+int(%d)
 [1]=
 string(3) =
 [2]=
@@ -751,7 +751,7 @@ array(94) {
   [88]=
   array(3) {
 [0]=
-int(273)
+int(%d)
 [1]=
 string(2) .=
 [2]=
diff --git a/ext/tokenizer/tests/token_get_all_variation6.phpt 
b/ext/tokenizer/tests/token_get_all_variation6.phpt
index 54936d0..6213dab 100644
--- a/ext/tokenizer/tests/token_get_all_variation6.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation6.phpt
@@ -191,7 +191,7 @@ array(50) {
   [21]=
   array(3) {
 [0]=
-int(287)
+int(%d)
 [1]=
 string(2) 
 [2]=
@@ -277,7 +277,7 @@ array(50) {
   [32]=
   array(3) {
 [0]=
-int(286)
+int(%d)
 [1]=
 string(2) 
 [2]=
diff --git a/ext/tokenizer/tests/token_get_all_variation8.phpt 

[PHP-CVS] com php-src: Remove reference restrictions from foreach: Zend/tests/errmsg_043.phpt Zend/tests/foreach_temp_array_expr_with_refs.phpt Zend/tests/generators/yield_by_reference.phpt Zend/zend_

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:de80e3ce4b5b7a9ec0cfdd0778e77027a7ebfcc2
Author:Nikita Popov ni...@php.net Sun, 22 Jul 2012 14:33:25 +0200
Parents:   80748631aa1c4193cbc68f8854d82e7a57817fe2
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=de80e3ce4b5b7a9ec0cfdd0778e77027a7ebfcc2

Log:
Remove reference restrictions from foreach

foreach only allowed variables to be traversed by reference. This never
really made sense because

a) Expressions like array($a, $b) can be meaningfully iterated by-ref
b) Function calls can return by-ref (so they can also be meaningfully
   iterated)
c) Iterators could at least in theory also be iterated by-ref (not
   sure if any iterator makes use of this)

With by-ref generators the restriction makes even less sense, so I removed
it altogether.

Changed paths:
  D  Zend/tests/errmsg_043.phpt
  A  Zend/tests/foreach_temp_array_expr_with_refs.phpt
  M  Zend/tests/generators/yield_by_reference.phpt
  M  Zend/zend_compile.c
  M  Zend/zend_language_parser.y
  D  tests/lang/foreachLoop.008.phpt


Diff:
diff --git a/Zend/tests/errmsg_043.phpt b/Zend/tests/errmsg_043.phpt
deleted file mode 100644
index 3de8bc2..000
--- a/Zend/tests/errmsg_043.phpt
+++ /dev/null
@@ -1,12 +0,0 @@
---TEST--
-errmsg: cannot create references to temp array
---FILE--
-?php
-
-foreach (array(1,2,3) as $k=$v) {
-}
-
-echo Done\n;
-?
---EXPECTF--
-Fatal error: Cannot create references to elements of a temporary array 
expression in %s on line %d
diff --git a/Zend/tests/foreach_temp_array_expr_with_refs.phpt 
b/Zend/tests/foreach_temp_array_expr_with_refs.phpt
new file mode 100644
index 000..8978b7b
--- /dev/null
+++ b/Zend/tests/foreach_temp_array_expr_with_refs.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Temporary array expressions can be iterated by reference
+--FILE--
+?php
+
+$a = 'a';
+$b = 'b';
+
+foreach ([$a, $b] as $value) {
+$value .= '-foo';
+}
+
+var_dump($a, $b);
+
+?
+--EXPECT--
+string(5) a-foo
+string(5) b-foo
diff --git a/Zend/tests/generators/yield_by_reference.phpt 
b/Zend/tests/generators/yield_by_reference.phpt
index 5a6c169..dba0791 100644
--- a/Zend/tests/generators/yield_by_reference.phpt
+++ b/Zend/tests/generators/yield_by_reference.phpt
@@ -9,24 +9,34 @@ function iter(array $array) {
 }
 }
 
-$array = [1, 2, 3, 4, 5];
+$array = [1, 2, 3];
 $iter = iter($array);
 foreach ($iter as $value) {
 $value *= -1;
 }
 var_dump($array);
 
+$array = [1, 2, 3];
+foreach (iter($array) as $value) {
+$value *= -1;
+}
+var_dump($array);
+
 ?
 --EXPECT--
-array(5) {
+array(3) {
+  [0]=
+  int(-1)
+  [1]=
+  int(-2)
+  [2]=
+  int(-3)
+}
+array(3) {
   [0]=
   int(-1)
   [1]=
   int(-2)
   [2]=
-  int(-3)
-  [3]=
-  int(-4)
-  [4]=
-  int(-5)
+  int(-3)
 }
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 51fc8c3..f0648a2 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -6317,9 +6317,7 @@ void zend_do_foreach_cont(znode *foreach_token, const 
znode *open_brackets_token
 
if (value-EA  ZEND_PARSED_REFERENCE_VARIABLE) {
assign_by_ref = 1;
-   if (!(opline-1)-extended_value) {
-   zend_error(E_COMPILE_ERROR, Cannot create references 
to elements of a temporary array expression);
-   }
+
/* Mark extended_value for assign-by-reference */
opline-extended_value |= ZEND_FE_FETCH_BYREF;

CG(active_op_array)-opcodes[foreach_token-u.op.opline_num].extended_value |= 
ZEND_FE_RESET_REFERENCE;
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index e5f31b5..4221752 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -312,7 +312,7 @@ unticked_statement:
foreach_statement { zend_do_foreach_end($1, $4 TSRMLS_CC); }
|   T_FOREACH '(' expr_without_variable T_AS
{ zend_do_foreach_begin($1, $2, $3, $4, 0 TSRMLS_CC); }
-   variable foreach_optional_arg ')' { 
zend_check_writable_variable($6); zend_do_foreach_cont($1, $2, $4, $6, $7 
TSRMLS_CC); }
+   foreach_variable foreach_optional_arg ')' { 
zend_do_foreach_cont($1, $2, $4, $6, $7 TSRMLS_CC); }
foreach_statement { zend_do_foreach_end($1, $4 TSRMLS_CC); }
|   T_DECLARE { $1.u.op.opline_num = 
get_next_op_number(CG(active_op_array)); zend_do_declare_begin(TSRMLS_C); } '(' 
declare_list ')' declare_statement { zend_do_declare_end($1 TSRMLS_CC); }
|   ';' /* empty statement */
diff --git a/tests/lang/foreachLoop.008.phpt b/tests/lang/foreachLoop.008.phpt
deleted file mode 100644
index 787f43b..000
--- a/tests/lang/foreachLoop.008.phpt
+++ /dev/null
@@ -1,10 +0,0 @@
---TEST--
-Foreach loop tests - error case: reference to constant array, with key.
---FILE--
-?php
-foreach (array(1,2) as $k=$v) {
-  var_dump($v);
-}
-?
---EXPECTF--
-Fatal error: Cannot create references to elements of a temporary array 

[PHP-CVS] com php-src: Add some more tests: Zend/tests/generators/fibonacci.phpt Zend/tests/generators/generator_closure.phpt Zend/tests/generators/generator_closure_with_this.phpt Zend/tests/generato

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:1f70a4c5fea97aa577aa5d9ee5f33d91d70e690d
Author:Nikita Popov ni...@php.net Fri, 20 Jul 2012 17:40:04 +0200
Parents:   612c2490b7973d71d472860ade48d7ab342b5911
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=1f70a4c5fea97aa577aa5d9ee5f33d91d70e690d

Log:
Add some more tests

Changed paths:
  A  Zend/tests/generators/fibonacci.phpt
  A  Zend/tests/generators/generator_closure.phpt
  A  Zend/tests/generators/generator_closure_with_this.phpt
  A  Zend/tests/generators/generator_static_method.phpt


Diff:
diff --git a/Zend/tests/generators/fibonacci.phpt 
b/Zend/tests/generators/fibonacci.phpt
new file mode 100644
index 000..35b3135
--- /dev/null
+++ b/Zend/tests/generators/fibonacci.phpt
@@ -0,0 +1,36 @@
+--TEST--
+Creating an infinite fibonacci list using a generator
+--FILE--
+?php
+
+function fib() {
+list($a, $b) = [1, 1];
+while (true) {
+yield $b;
+list($a, $b) = [$b, $a + $b];
+}
+}
+
+foreach (fib() as $n) {
+if ($n  1000) break;
+
+var_dump($n);
+}
+
+?
+--EXPECT--
+int(1)
+int(2)
+int(3)
+int(5)
+int(8)
+int(13)
+int(21)
+int(34)
+int(55)
+int(89)
+int(144)
+int(233)
+int(377)
+int(610)
+int(987)
diff --git a/Zend/tests/generators/generator_closure.phpt 
b/Zend/tests/generators/generator_closure.phpt
new file mode 100644
index 000..bf80066
--- /dev/null
+++ b/Zend/tests/generators/generator_closure.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Closures can be generators
+--FILE--
+?php
+
+$genFactory = function() {
+yield 1;
+yield 2;
+yield 3;
+};
+
+foreach ($genFactory() as $value) {
+var_dump($value);
+}
+
+?
+--EXPECT--
+int(1)
+int(2)
+int(3)
diff --git a/Zend/tests/generators/generator_closure_with_this.phpt 
b/Zend/tests/generators/generator_closure_with_this.phpt
new file mode 100644
index 000..d5a4861
--- /dev/null
+++ b/Zend/tests/generators/generator_closure_with_this.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Non-static closures can be generators
+--FILE--
+?php
+
+class Test {
+public function getGenFactory() {
+return function() {
+yield $this;
+};
+}
+}
+
+$genFactory = (new Test)-getGenFactory();
+var_dump($genFactory()-current());
+
+?
+--EXPECT--
+object(Test)#1 (0) {
+}
diff --git a/Zend/tests/generators/generator_static_method.phpt 
b/Zend/tests/generators/generator_static_method.phpt
new file mode 100644
index 000..cd9b450
--- /dev/null
+++ b/Zend/tests/generators/generator_static_method.phpt
@@ -0,0 +1,29 @@
+--TEST--
+A static method can be a generator
+--FILE--
+?php
+
+class Test {
+public static function gen() {
+var_dump(get_class());
+var_dump(get_called_class());
+yield 1;
+yield 2;
+yield 3;
+}
+}
+
+class ExtendedTest extends Test {
+}
+
+foreach (ExtendedTest::gen() as $i) {
+var_dump($i);
+}
+
+?
+--EXPECT--
+string(4) Test
+string(12) ExtendedTest
+int(1)
+int(2)
+int(3)


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] svn: /SVNROOT/ global_avail

2012-09-01 Thread Felipe Pena
felipe   Sat, 01 Sep 2012 17:27:21 +

Revision: http://svn.php.net/viewvc?view=revisionrevision=327420

Log:
- Granted Zend karma to Nikita Popov (nikic)

Changed paths:
U   SVNROOT/global_avail

Modified: SVNROOT/global_avail
===
--- SVNROOT/global_avail2012-09-01 14:51:06 UTC (rev 327419)
+++ SVNROOT/global_avail2012-09-01 17:27:21 UTC (rev 327420)
@@ -48,7 +48,7 @@
 avail|loudi,mrkschan,pmjones,irker|phd.git,web/doc.git,web/doc-editor.git

 # People who work on the Engine - not people with just tests access
-avail|andi,zeev,andrei,stas,sterling,sas,derick,sebastian,phanto,jani,hirokawa,fujimoto,rvenkat,sesser,kalowsky,iliaa,hyanantha,georg,wez,edink,helly,hholzgra,imajes,gschlossnagle,moriyoshi,dmitry,jon,pollita,tony2001,johannes,bjori,davidw,nicholsr,wharmby,felipe,robinf,scottmac,nlopess,mattwil,colder,lbarnaud,pajoye,cseiler,dsp,shire,gron,gopalv,gwynne,pierrick,laruence,cataphract,ab,lstrojny|php-src.git/Zend,php-src.git/TSRM
+avail|andi,zeev,andrei,stas,sterling,sas,derick,sebastian,phanto,jani,hirokawa,fujimoto,rvenkat,sesser,kalowsky,iliaa,hyanantha,georg,wez,edink,helly,hholzgra,imajes,gschlossnagle,moriyoshi,dmitry,jon,pollita,tony2001,johannes,bjori,davidw,nicholsr,wharmby,felipe,robinf,scottmac,nlopess,mattwil,colder,lbarnaud,pajoye,cseiler,dsp,shire,gron,gopalv,gwynne,pierrick,laruence,cataphract,ab,lstrojny,nikic|php-src.git/Zend,php-src.git/TSRM

 # The PHP Documentation Group maintains the documentation and its
 # translations.

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

[PHP-CVS] com php-src: Forgot to git add two tests: Zend/tests/generators/close_inside_generator.phpt Zend/tests/generators/func_get_args.phpt

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:5a9bddba6699d056383107728392048cd7ccb598
Author:Nikita Popov ni...@php.net Mon, 25 Jun 2012 21:41:50 +0200
Parents:   ab75ed6ba9b5eace710976bf76d631728d4bb403
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=5a9bddba6699d056383107728392048cd7ccb598

Log:
Forgot to git add two tests

Changed paths:
  A  Zend/tests/generators/close_inside_generator.phpt
  A  Zend/tests/generators/func_get_args.phpt


Diff:
diff --git a/Zend/tests/generators/close_inside_generator.phpt 
b/Zend/tests/generators/close_inside_generator.phpt
new file mode 100644
index 000..41a91c9
--- /dev/null
+++ b/Zend/tests/generators/close_inside_generator.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Calling close() during the exectution of the generator
+--FILE--
+?php
+
+function *gen() {
+/* Pass the generator object itself in */
+$gen = yield;
+
+/* Close generator while it is currently running */
+$gen-close();
+
+   echo Still running;
+}
+
+$gen = gen();
+$gen-send($gen);
+
+?
+--EXPECTF--
+Warning: A generator cannot be closed while it is running in %s on line %d
+Still running
diff --git a/Zend/tests/generators/func_get_args.phpt 
b/Zend/tests/generators/func_get_args.phpt
new file mode 100644
index 000..7ce7fb0
--- /dev/null
+++ b/Zend/tests/generators/func_get_args.phpt
@@ -0,0 +1,20 @@
+--TEST--
+func_get_args() can be used inside generator functions
+--FILE--
+?php
+
+function *gen() {
+var_dump(func_get_args());
+}
+
+$gen = gen(foo, bar);
+$gen-rewind();
+
+?
+--EXPECT--
+array(2) {
+  [0]=
+  string(3) foo
+  [1]=
+  string(3) bar
+}


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Implement get_iterator: Zend/zend_generators.c

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:04e781f0e4a4ea879c5e85b8d209b9b44cc32f8d
Author:Nikita Popov ni...@php.net Sat, 23 Jun 2012 01:28:16 +0200
Parents:   1d3f37ddedc931d700a4e1135f63e094df88dbc4
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=04e781f0e4a4ea879c5e85b8d209b9b44cc32f8d

Log:
Implement get_iterator

This implements the get_iterator handler for Generator objects, thus making
direct foreach() iteration significantly faster.

Changed paths:
  M  Zend/zend_generators.c


Diff:
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index b7538e7..10d91f5 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -564,6 +564,114 @@ ZEND_METHOD(Generator, close)
 }
 /* }}} */
 
+/* get_iterator implementation */
+
+typedef struct _zend_generator_iterator {
+   zend_object_iterator intern;
+   zend_generator *generator;
+} zend_generator_iterator;
+
+static void zend_generator_iterator_dtor(zend_object_iterator *iterator 
TSRMLS_DC) /* {{{ */
+{
+   zval_ptr_dtor((zval **) iterator-data);
+   efree(iterator);
+}
+/* }}} */
+
+static int zend_generator_iterator_valid(zend_object_iterator *iterator 
TSRMLS_DC) /* {{{ */
+{
+   zval *object = (zval *) iterator-data;
+   zend_generator *generator = ((zend_generator_iterator *) 
iterator)-generator;
+
+   zend_generator_ensure_initialized(object, generator TSRMLS_CC);
+
+   return generator-value != NULL ? SUCCESS : FAILURE;
+}
+/* }}} */
+
+static void zend_generator_iterator_get_data(zend_object_iterator *iterator, 
zval ***data TSRMLS_DC) /* {{{ */
+{
+   zval *object = (zval *) iterator-data;
+   zend_generator *generator = ((zend_generator_iterator *) 
iterator)-generator;
+
+   zend_generator_ensure_initialized(object, generator TSRMLS_CC);
+
+   if (generator-value) {
+   *data = generator-value;
+   } else {
+   *data = NULL;
+   }
+}
+/* }}} */
+
+static int zend_generator_iterator_get_key(zend_object_iterator *iterator, 
char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
+{
+   zval *object = (zval *) iterator-data;
+   zend_generator *generator = ((zend_generator_iterator *) 
iterator)-generator;
+
+   zend_generator_ensure_initialized(object, generator TSRMLS_CC);
+
+   if (!generator-key) {
+   return HASH_KEY_NON_EXISTANT;
+   }
+
+   if (Z_TYPE_P(generator-key) == IS_LONG) {
+   *int_key = Z_LVAL_P(generator-key);
+   return HASH_KEY_IS_LONG;
+   }
+
+   if (Z_TYPE_P(generator-key) == IS_STRING) {
+   *str_key = estrndup(Z_STRVAL_P(generator-key), 
Z_STRLEN_P(generator-key));
+   *str_key_len = Z_STRLEN_P(generator-key) + 1;
+   return HASH_KEY_IS_STRING;
+   }
+
+   /* Waiting for Etienne's patch to allow arbitrary zval keys. Until then
+* error out on non-int and non-string keys. */
+   zend_error(E_ERROR, Currently only int and string keys can be 
yielded);
+}
+/* }}} */
+
+static void zend_generator_iterator_move_forward(zend_object_iterator 
*iterator TSRMLS_DC) /* {{{ */
+{
+   zval *object = (zval *) iterator-data;
+   zend_generator *generator = ((zend_generator_iterator *) 
iterator)-generator;
+
+   zend_generator_ensure_initialized(object, generator TSRMLS_CC);
+
+   zend_generator_resume(object, generator TSRMLS_CC);
+}
+/* }}} */
+
+static zend_object_iterator_funcs zend_generator_iterator_functions = {
+   zend_generator_iterator_dtor,
+   zend_generator_iterator_valid,
+   zend_generator_iterator_get_data,
+   zend_generator_iterator_get_key,
+   zend_generator_iterator_move_forward,
+   NULL
+};
+
+zend_object_iterator *zend_generator_get_iterator(zend_class_entry *ce, zval 
*object, int by_ref TSRMLS_DC) /* {{{ */
+{
+   zend_generator_iterator *iterator;
+
+   if (by_ref) {
+   zend_error(E_ERROR, By reference iteration of generators is 
currently not supported);
+   }
+
+   iterator = emalloc(sizeof(zend_generator_iterator));
+   iterator-intern.funcs = zend_generator_iterator_functions;
+
+   Z_ADDREF_P(object);
+   iterator-intern.data = (void *) object;
+   
+   iterator-generator = zend_object_store_get_object(object TSRMLS_CC);
+
+   return (zend_object_iterator *) iterator;
+}
+/* }}} */
+
 ZEND_BEGIN_ARG_INFO(arginfo_generator_void, 0)
 ZEND_END_ARG_INFO()
 
@@ -590,6 +698,7 @@ void zend_register_generator_ce(TSRMLS_D) /* {{{ */
zend_ce_generator = zend_register_internal_class(ce TSRMLS_CC);
zend_ce_generator-ce_flags |= ZEND_ACC_FINAL_CLASS;
zend_ce_generator-create_object = zend_generator_create;
+   zend_ce_generator-get_iterator = zend_generator_get_iterator;
 
zend_class_implements(zend_ce_generator TSRMLS_CC, 1, zend_ce_iterator);


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[PHP-CVS] com php-src: Disallow closing a generator during its execution: Zend/zend_generators.c Zend/zend_generators.h

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:ab75ed6ba9b5eace710976bf76d631728d4bb403
Author:Nikita Popov ni...@php.net Sat, 23 Jun 2012 16:08:15 +0200
Parents:   14766e1417c721d9643f6a2a785db3e88b565814
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=ab75ed6ba9b5eace710976bf76d631728d4bb403

Log:
Disallow closing a generator during its execution

If a generator is closed while it is running an E_WARNING is thrown and the
call is ignored. Maybe a fatal error should be thrown instead?

Changed paths:
  M  Zend/zend_generators.c
  M  Zend/zend_generators.h


Diff:
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 487975e..bccbb48 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -300,6 +300,8 @@ static zend_object_value 
zend_generator_create(zend_class_entry *class_type TSRM
/* The key will be incremented on first use, so it'll start at 0 */
generator-largest_used_integer_key = -1;
 
+   generator-is_currently_running = 0;
+
zend_object_std_init(generator-std, class_type TSRMLS_CC);
 
object.handle = zend_objects_store_put(generator, NULL,
@@ -339,6 +341,8 @@ static void zend_generator_resume(zend_generator *generator 
TSRMLS_DC) /* {{{ */
zend_class_entry *original_scope = EG(scope);
zend_class_entry *original_called_scope = EG(called_scope);
 
+   zend_bool original_is_currently_running = 
generator-is_currently_running;
+
/* Remember the current stack position so we can back up pushed 
args */
generator-original_stack_top = zend_vm_stack_top(TSRMLS_C);
 
@@ -363,6 +367,8 @@ static void zend_generator_resume(zend_generator *generator 
TSRMLS_DC) /* {{{ */
EG(scope) = generator-execute_data-current_scope;
EG(called_scope) = 
generator-execute_data-current_called_scope;
 
+   generator-is_currently_running = 1;
+
/* We want the backtrace to look as if the generator function 
was
 * called from whatever method we are current running (e.g. 
next()).
 * The first prev_execute_data contains an additional stack 
frame,
@@ -387,6 +393,8 @@ static void zend_generator_resume(zend_generator *generator 
TSRMLS_DC) /* {{{ */
EG(scope) = original_scope;
EG(called_scope) = original_called_scope;
 
+   generator-is_currently_running = original_is_currently_running;
+
/* The stack top before and after the execution differ, i.e. 
there are
 * arguments pushed to the stack. */
if (generator-original_stack_top != 
zend_vm_stack_top(TSRMLS_C)) {
@@ -549,6 +557,11 @@ ZEND_METHOD(Generator, close)
 
generator = (zend_generator *) zend_object_store_get_object(getThis() 
TSRMLS_CC);
 
+   if (generator-is_currently_running) {
+   zend_error(E_WARNING, A generator cannot be closed while it is 
running);
+   return;
+   }
+
zend_generator_close(generator, 0 TSRMLS_CC);
 }
 /* }}} */
diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h
index 89193bb..73d85287 100644
--- a/Zend/zend_generators.h
+++ b/Zend/zend_generators.h
@@ -46,6 +46,10 @@ typedef struct _zend_generator {
temp_variable *send_target;
/* Largest used integer key for auto-incrementing keys */
long largest_used_integer_key;
+
+   /* We need to know whether the generator is currently executed to avoid 
it
+* being closed while still running */
+   zend_bool is_currently_running;
 } zend_generator;
 
 extern ZEND_API zend_class_entry *zend_ce_generator;


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Pass zend_generator directly to Zend VM: Zend/zend_generators.c Zend/zend_vm_def.h Zend/zend_vm_execute.h

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:14766e1417c721d9643f6a2a785db3e88b565814
Author:Nikita Popov ni...@php.net Sat, 23 Jun 2012 14:43:52 +0200
Parents:   04e781f0e4a4ea879c5e85b8d209b9b44cc32f8d
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=14766e1417c721d9643f6a2a785db3e88b565814

Log:
Pass zend_generator directly to Zend VM

Previously the zval* of the generator was passed into the VM by misusing
EG(return_value_ptr_ptr). Now the zend_generator* itself is directly passed
in. This saves us from always having to pass the zval* around everywhere.

Changed paths:
  M  Zend/zend_generators.c
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h

diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 10d91f5..487975e 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -321,7 +321,7 @@ static zend_function *zend_generator_get_constructor(zval 
*object TSRMLS_DC) /*
 }
 /* }}} */
 
-static void zend_generator_resume(zval *object, zend_generator *generator 
TSRMLS_DC) /* {{{ */
+static void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{ 
*/
 {
/* The generator is already closed, thus can't resume */
if (!generator-execute_data) {
@@ -352,7 +352,7 @@ static void zend_generator_resume(zval *object, 
zend_generator *generator TSRMLS
 
/* We (mis)use the return_value_ptr_ptr to provide the 
generator object
 * to the executor, so YIELD will be able to set the yielded 
value */
-   EG(return_value_ptr_ptr) = object;
+   EG(return_value_ptr_ptr) = (zval **) generator;
 
/* Set executor globals */
EG(current_execute_data) = generator-execute_data;
@@ -399,10 +399,10 @@ static void zend_generator_resume(zval *object, 
zend_generator *generator TSRMLS
 }
 /* }}} */
 
-static void zend_generator_ensure_initialized(zval *object, zend_generator 
*generator TSRMLS_DC) /* {{{ */
+static void zend_generator_ensure_initialized(zend_generator *generator 
TSRMLS_DC) /* {{{ */
 {
if (!generator-value) {
-   zend_generator_resume(object, generator TSRMLS_CC);
+   zend_generator_resume(generator TSRMLS_CC);
}
 }
 /* }}} */
@@ -411,17 +411,15 @@ static void zend_generator_ensure_initialized(zval 
*object, zend_generator *gene
  * Rewind the generator */
 ZEND_METHOD(Generator, rewind)
 {
-   zval *object;
zend_generator *generator;
 
if (zend_parse_parameters_none() == FAILURE) {
return;
}
 
-   object = getThis();
-   generator = (zend_generator *) zend_object_store_get_object(object 
TSRMLS_CC);
+   generator = (zend_generator *) zend_object_store_get_object(getThis() 
TSRMLS_CC);
 
-   zend_generator_ensure_initialized(object, generator TSRMLS_CC);
+   zend_generator_ensure_initialized(generator TSRMLS_CC);
 
/* Generators aren't rewindable, so rewind() only has to make sure that
 * the generator is initialized, nothing more */
@@ -432,17 +430,15 @@ ZEND_METHOD(Generator, rewind)
  * Check whether the generator is valid */
 ZEND_METHOD(Generator, valid)
 {
-   zval *object;
zend_generator *generator;
 
if (zend_parse_parameters_none() == FAILURE) {
return;
}
 
-   object = getThis();
-   generator = (zend_generator *) zend_object_store_get_object(object 
TSRMLS_CC);
+   generator = (zend_generator *) zend_object_store_get_object(getThis() 
TSRMLS_CC);
 
-   zend_generator_ensure_initialized(object, generator TSRMLS_CC);
+   zend_generator_ensure_initialized(generator TSRMLS_CC);
 
RETURN_BOOL(generator-value != NULL);
 }
@@ -452,17 +448,15 @@ ZEND_METHOD(Generator, valid)
  * Get the current value */
 ZEND_METHOD(Generator, current)
 {
-   zval *object;
zend_generator *generator;
 
if (zend_parse_parameters_none() == FAILURE) {
return;
}
 
-   object = getThis();
-   generator = (zend_generator *) zend_object_store_get_object(object 
TSRMLS_CC);
+   generator = (zend_generator *) zend_object_store_get_object(getThis() 
TSRMLS_CC);
 
-   zend_generator_ensure_initialized(object, generator TSRMLS_CC);
+   zend_generator_ensure_initialized(generator TSRMLS_CC);
 
if (generator-value) {
RETURN_ZVAL(generator-value, 1, 0);
@@ -474,17 +468,15 @@ ZEND_METHOD(Generator, current)
  * Get the current key */
 ZEND_METHOD(Generator, key)
 {
-   zval *object;
zend_generator *generator;
 
if (zend_parse_parameters_none() == FAILURE) {
return;
}
 
-   object = getThis();
-   generator = (zend_generator *) zend_object_store_get_object(object 
TSRMLS_CC);
+   generator = (zend_generator *) zend_object_store_get_object(getThis() 
TSRMLS_CC);
 
-   zend_generator_ensure_initialized(object, generator TSRMLS_CC);
+   

[PHP-CVS] com php-src: Add sceleton for yield* expression: Zend/tests/generators/errors/yield_in_normal_function_error.phpt Zend/tests/generators/errors/yield_outside_function_error.phpt Zend/zend_com

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:d939d2dee58bf894ae9af631bdee173243157068
Author:Nikita Popov ni...@php.net Mon, 11 Jun 2012 23:59:46 +0200
Parents:   f169b26dd7a4047996ab1284e649fda0cfb1a10b
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=d939d2dee58bf894ae9af631bdee173243157068

Log:
Add sceleton for yield* expression

This does not yet actually implement any delegation.

Changed paths:
  M  Zend/tests/generators/errors/yield_in_normal_function_error.phpt
  M  Zend/tests/generators/errors/yield_outside_function_error.phpt
  M  Zend/zend_compile.c
  M  Zend/zend_compile.h
  M  Zend/zend_generators.c
  M  Zend/zend_language_parser.y
  M  Zend/zend_language_scanner.c
  M  Zend/zend_language_scanner_defs.h
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h
  M  Zend/zend_vm_opcodes.h

diff --git a/Zend/tests/generators/errors/yield_in_normal_function_error.phpt 
b/Zend/tests/generators/errors/yield_in_normal_function_error.phpt
index 802510d..4670a41 100644
--- a/Zend/tests/generators/errors/yield_in_normal_function_error.phpt
+++ b/Zend/tests/generators/errors/yield_in_normal_function_error.phpt
@@ -9,4 +9,4 @@ function foo() {
 
 ?
 --EXPECTF--
-Fatal error: The yield statement can only be used inside a generator 
function in %s on line %d
+Fatal error: The yield expression can only be used inside a generator 
function in %s on line %d
diff --git a/Zend/tests/generators/errors/yield_outside_function_error.phpt 
b/Zend/tests/generators/errors/yield_outside_function_error.phpt
index fd7169d..5f47e75 100644
--- a/Zend/tests/generators/errors/yield_outside_function_error.phpt
+++ b/Zend/tests/generators/errors/yield_outside_function_error.phpt
@@ -7,4 +7,4 @@ yield Test;
 
 ?
 --EXPECTF--
-Fatal error: The yield statement can only be used inside a generator 
function in %s on line %d
+Fatal error: The yield expression can only be used inside a generator 
function in %s on line %d
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index da61b76..35ff2bb 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2667,7 +2667,7 @@ void zend_do_yield(znode *result, const znode *value, 
const znode *key TSRMLS_DC
zend_op *opline;
 
if ((CG(active_op_array)-fn_flags  ZEND_ACC_GENERATOR) == 0) {
-   zend_error(E_COMPILE_ERROR, The \yield\ statement can only 
be used inside a generator function);
+   zend_error(E_COMPILE_ERROR, The \yield\ expression can only 
be used inside a generator function);
}
 
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
@@ -2692,6 +2692,27 @@ void zend_do_yield(znode *result, const znode *value, 
const znode *key TSRMLS_DC
 }
 /* }}} */
 
+void zend_do_delegate_yield(znode *result, const znode *value TSRMLS_DC) /* 
{{{ */
+{
+   zend_op *opline;
+
+   if ((CG(active_op_array)-fn_flags  ZEND_ACC_GENERATOR) == 0) {
+   zend_error(E_COMPILE_ERROR, The \yield*\ expression can only 
be used inside a generator function);
+   }
+
+   opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+
+   opline-opcode = ZEND_DELEGATE_YIELD;
+
+   SET_NODE(opline-op1, value);
+   SET_UNUSED(opline-op2);
+
+   opline-result_type = IS_VAR;
+   opline-result.var = get_temporary_variable(CG(active_op_array));
+   GET_NODE(result, opline-result);
+}
+/* }}} */
+
 void zend_do_suspend_if_generator(TSRMLS_D) /* {{{ */
 {
zend_op *opline;
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index ec86ed8..d0587d1 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -491,6 +491,7 @@ int zend_do_begin_class_member_function_call(znode 
*class_name, znode *method_na
 void zend_do_end_function_call(znode *function_name, znode *result, const 
znode *argument_list, int is_method, int is_dynamic_fcall TSRMLS_DC);
 void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC);
 void zend_do_yield(znode *result, const znode *value, const znode *key 
TSRMLS_DC);
+void zend_do_delegate_yield(znode *result, const znode *value TSRMLS_DC);
 void zend_do_suspend_if_generator(TSRMLS_D);
 void zend_do_handle_exception(TSRMLS_D);
 
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 6efa710..f8374b8 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -245,7 +245,7 @@ static void zend_generator_clone_storage(zend_generator 
*orig, zend_generator **
}
 
/* Update the send_target to use the temporary variable with 
the same
-* offset as the original generator, but in out temporary 
variable
+* offset as the original generator, but in our temporary 
variable
 * memory segment. */
if (orig-send_target) {
size_t offset = (char *) orig-send_target - (char *) 
execute_data-Ts;
@@ -536,7 +536,6 @@ ZEND_METHOD(Generator, send)
/* The sent value was initialized to NULL, so dtor that */

[PHP-CVS] com php-src: Fix thread safe build: Zend/zend_execute.c Zend/zend_execute.h Zend/zend_generators.c Zend/zend_vm_def.h Zend/zend_vm_execute.h

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:6233408a2a51389a2bbd250c5900d395648e897f
Author:Nikita Popov ni...@php.net Wed, 20 Jun 2012 21:31:23 +0200
Parents:   d939d2dee58bf894ae9af631bdee173243157068
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=6233408a2a51389a2bbd250c5900d395648e897f

Log:
Fix thread safe build

Changed paths:
  M  Zend/zend_execute.c
  M  Zend/zend_execute.h
  M  Zend/zend_generators.c
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h


Diff:
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index c7ef212..0e40650 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -1538,7 +1538,7 @@ ZEND_API zval **zend_get_zval_ptr_ptr(int op_type, const 
znode_op *node, const t
return get_zval_ptr_ptr(op_type, node, Ts, should_free, type);
 }
 
-void zend_clean_and_cache_symbol_table(HashTable *symbol_table) /* {{{ */
+void zend_clean_and_cache_symbol_table(HashTable *symbol_table TSRMLS_DC) /* 
{{{ */
 {
if (EG(symtable_cache_ptr) = EG(symtable_cache_limit)) {
zend_hash_destroy(symbol_table);
diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h
index 48f46bb..92160b5 100644
--- a/Zend/zend_execute.h
+++ b/Zend/zend_execute.h
@@ -432,7 +432,7 @@ ZEND_API zval **zend_get_zval_ptr_ptr(int op_type, const 
znode_op *node, const t
 
 ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS);
 
-void zend_clean_and_cache_symbol_table(HashTable *symbol_table);
+void zend_clean_and_cache_symbol_table(HashTable *symbol_table TSRMLS_DC);
 void zend_free_compiled_variables(zval ***CVs, int num);
 void **zend_copy_arguments(void **arguments_end);
 
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index f8374b8..b7538e7 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -34,7 +34,7 @@ void zend_generator_close(zend_generator *generator, 
zend_bool finished_executio
if (!execute_data-symbol_table) {
zend_free_compiled_variables(execute_data-CVs, 
execute_data-op_array-last_var);
} else {
-   
zend_clean_and_cache_symbol_table(execute_data-symbol_table);
+   
zend_clean_and_cache_symbol_table(execute_data-symbol_table TSRMLS_CC);
}
 
if (execute_data-current_this) {
@@ -560,7 +560,7 @@ ZEND_METHOD(Generator, close)
 
generator = (zend_generator *) zend_object_store_get_object(getThis() 
TSRMLS_CC);
 
-   zend_generator_close(generator, 0);
+   zend_generator_close(generator, 0 TSRMLS_CC);
 }
 /* }}} */
 
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index e5d8a76..fea1f40 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2572,7 +2572,7 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
EG(active_op_array) = EX(op_array);
EG(return_value_ptr_ptr) = EX(original_return_value);
if (EG(active_symbol_table)) {
-   
zend_clean_and_cache_symbol_table(EG(active_symbol_table));
+   
zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
}
EG(active_symbol_table) = EX(symbol_table);
 
@@ -2717,7 +2717,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
EG(active_op_array) = EX(op_array);
EG(return_value_ptr_ptr) = EX(original_return_value);
if (EG(active_symbol_table)) {
-   
zend_clean_and_cache_symbol_table(EG(active_symbol_table));
+   
zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
}
EG(active_symbol_table) = EX(symbol_table);
} else { /* ZEND_OVERLOADED_FUNCTION */
@@ -5265,7 +5265,7 @@ ZEND_VM_HANDLER(159, ZEND_SUSPEND_AND_RETURN_GENERATOR, 
ANY, ANY)
if (!EG(active_symbol_table)) {
zend_free_compiled_variables(EX_CVs(), 
execute_data-op_array-last_var);
} else {
-   
zend_clean_and_cache_symbol_table(EG(active_symbol_table));
+   
zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
}
efree(execute_data);
}
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 6f1a885..0f965c5 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -556,7 +556,7 @@ static int ZEND_FASTCALL 
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
EG(active_op_array) = EX(op_array);
EG(return_value_ptr_ptr) = EX(original_return_value);
if (EG(active_symbol_table)) {
-   
zend_clean_and_cache_symbol_table(EG(active_symbol_table));
+   
zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
}

[PHP-CVS] com php-src: Fix backtraces and func_get_args(): Zend/tests/generators/backtrace.phpt Zend/zend_execute.c Zend/zend_execute.h Zend/zend_generators.c Zend/zend_vm_def.h Zend/zend_vm_execute.h

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:f169b26dd7a4047996ab1284e649fda0cfb1a10b
Author:Nikita Popov ni...@php.net Sat, 9 Jun 2012 00:40:47 +0200
Parents:   40760ecb90d1b024c76862e33d13d40137650af7
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=f169b26dd7a4047996ab1284e649fda0cfb1a10b

Log:
Fix backtraces and func_get_args()

To make the generator function show up in backtraces one has to insert an
additional execute_data into the chain, as prev_execute_data-function_state
is used to determine the called function.

Adding the additional stack frame is also required for func_get_args(), as
the arguments are fetched from there too. The arguments have to be copied
in order to keep them around. Due to the way they are saved doing so is
quite ugly, so I added another function zend_copy_arguments to zend_execute.c
which handles this.

Changed paths:
  M  Zend/tests/generators/backtrace.phpt
  M  Zend/zend_execute.c
  M  Zend/zend_execute.h
  M  Zend/zend_generators.c
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h

diff --git a/Zend/tests/generators/backtrace.phpt 
b/Zend/tests/generators/backtrace.phpt
index cbf8de1..77976f9 100644
--- a/Zend/tests/generators/backtrace.phpt
+++ b/Zend/tests/generators/backtrace.phpt
@@ -7,7 +7,7 @@ function f1() {
 debug_print_backtrace();
 }
 
-function *f2() {
+function *f2($arg1, $arg2) {
 f1();
 }
 
@@ -15,11 +15,12 @@ function f3($gen) {
 $gen-rewind(); // trigger run
 }
 
-$gen = f2();
+$gen = f2('foo', 'bar');
 f3($gen);
 
 ?
 --EXPECTF--
 #0  f1() called at [%s:%d]
-#1  Generator-rewind() called at [%s:%d]
-#2  f3(Generator Object ()) called at [%s:%d]
+#1  f2(foo, bar) called at [%s:%d]
+#2  Generator-rewind() called at [%s:%d]
+#3  f3(Generator Object ()) called at [%s:%d]
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 9031fb5..c7ef212 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -1563,6 +1563,25 @@ void zend_free_compiled_variables(zval ***CVs, int num) 
/* {{{ */
 }
 /* }}} */
 
+void** zend_copy_arguments(void **arguments_end) /* {{{ */
+{
+   int arguments_count = (int) (zend_uintptr_t) *arguments_end;
+   size_t arguments_size = (arguments_count + 1) * sizeof(void **);
+   void **arguments_start = arguments_end - arguments_count;
+   void **copied_arguments_start = emalloc(arguments_size);
+   void **copied_arguments_end = copied_arguments_start + arguments_count;
+   int i;
+
+   memcpy(copied_arguments_start, arguments_start, arguments_size);
+
+   for (i = 0; i  arguments_count; i++) {
+   Z_ADDREF_P((zval *) arguments_start[i]);
+   }
+
+   return copied_arguments_end;
+}
+/* }}} */
+
 /*
  * Local variables:
  * tab-width: 4
diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h
index 6dfd607..48f46bb 100644
--- a/Zend/zend_execute.h
+++ b/Zend/zend_execute.h
@@ -434,6 +434,7 @@ ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS);
 
 void zend_clean_and_cache_symbol_table(HashTable *symbol_table);
 void zend_free_compiled_variables(zval ***CVs, int num);
+void **zend_copy_arguments(void **arguments_end);
 
 #define CACHED_PTR(num) \
EG(active_op_array)-run_time_cache[(num)]
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index b5642dd..6efa710 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -94,6 +94,28 @@ void zend_generator_close(zend_generator *generator, 
zend_bool finished_executio
efree(generator-backed_up_stack);
}
 
+   /* We have added an additional stack frame in 
prev_execute_data, so we
+* have to free it. It also contains the arguments passed to the
+* generator (for func_get_args) so those have to be freed too. 
*/
+   {
+   zend_execute_data *prev_execute_data = 
execute_data-prev_execute_data;
+   void **arguments = 
prev_execute_data-function_state.arguments;
+
+   if (arguments) {
+   int arguments_count = (int) (zend_uintptr_t) 
*arguments;
+   zval **arguments_start = (zval **) (arguments - 
arguments_count);
+   int i;
+
+   for (i = 0; i  arguments_count; ++i) {
+   zval_ptr_dtor(arguments_start + i);
+   }
+
+   efree(arguments_start);
+   }
+
+   efree(prev_execute_data);
+   }
+
efree(execute_data);
generator-execute_data = NULL;
}
@@ -240,6 +262,18 @@ static void zend_generator_clone_storage(zend_generator 
*orig, zend_generator **
if (execute_data-object) {
Z_ADDREF_P(execute_data-object);
}
+
+   /* Prev execute data contains an additional stack frame (for 
proper)

[PHP-CVS] com php-src: Fix cloning of generator methods: Zend/tests/generators/clone_with_this.phpt Zend/zend_generators.c

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:40760ecb90d1b024c76862e33d13d40137650af7
Author:Nikita Popov ni...@php.net Sun, 3 Jun 2012 02:40:03 +0200
Parents:   bf82f46ea9028faa3830525d2462effe7d08600d
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=40760ecb90d1b024c76862e33d13d40137650af7

Log:
Fix cloning of generator methods

Forgot to add a reference to the this variable

Changed paths:
  A  Zend/tests/generators/clone_with_this.phpt
  M  Zend/zend_generators.c


Diff:
diff --git a/Zend/tests/generators/clone_with_this.phpt 
b/Zend/tests/generators/clone_with_this.phpt
new file mode 100644
index 000..b0f28be
--- /dev/null
+++ b/Zend/tests/generators/clone_with_this.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Cloning a generator method (with this)
+--FILE--
+?php
+
+class Test {
+protected $foo;
+
+public function *gen() {
+$this-foo = 'bar';
+yield; // interrupt
+var_dump($this-foo);
+}
+}
+
+$g1 = (new Test)-gen();
+$g1-rewind(); // goto yield
+$g2 = clone $g1;
+$g1-close();
+$g2-next();
+
+?
+--EXPECT--
+string(3) bar
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index a3277e6..b5642dd 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -233,6 +233,10 @@ static void zend_generator_clone_storage(zend_generator 
*orig, zend_generator **
Z_ADDREF_P(clone-send_target-var.ptr);
}
 
+   if (execute_data-current_this) {
+   Z_ADDREF_P(execute_data-current_this);
+   }
+
if (execute_data-object) {
Z_ADDREF_P(execute_data-object);
}


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Properly handle yield during method calls: Zend/tests/generators/yield_during_method_call.phpt Zend/zend_generators.c

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:bf82f46ea9028faa3830525d2462effe7d08600d
Author:Nikita Popov ni...@php.net Sun, 3 Jun 2012 02:16:29 +0200
Parents:   7b3bfa5784cf36647f21a72ceb9741e40927a5b6
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=bf82f46ea9028faa3830525d2462effe7d08600d

Log:
Properly handle yield during method calls

Changed paths:
  A  Zend/tests/generators/yield_during_method_call.phpt
  M  Zend/zend_generators.c


Diff:
diff --git a/Zend/tests/generators/yield_during_method_call.phpt 
b/Zend/tests/generators/yield_during_method_call.phpt
new file mode 100644
index 000..da987ab
--- /dev/null
+++ b/Zend/tests/generators/yield_during_method_call.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Yield can be used during a method call
+--FILE--
+?php
+
+class A {
+public function b($c) {
+echo $c, \n;
+}
+}
+
+function *gen() {
+$a = new A;
+$a-b(yield);
+}
+
+$gen = gen();
+$gen-send('foo');
+
+// test resource cleanup
+$gen = gen();
+$gen-rewind();
+$gen-close();
+
+// test cloning
+$g1 = gen();
+$g1-rewind();
+$g2 = clone $g1;
+$g1-close();
+$g2-send('bar');
+
+?
+--EXPECT--
+foo
+bar
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index df204fa..a3277e6 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -41,6 +41,10 @@ void zend_generator_close(zend_generator *generator, 
zend_bool finished_executio
zval_ptr_dtor(execute_data-current_this);
}
 
+   if (execute_data-object) {
+   zval_ptr_dtor(execute_data-object);
+   }
+
/* If the generator is closed before it can finish execution 
(reach
 * a return statement) we have to free loop variables manually, 
as
 * we don't know whether the SWITCH_FREE / FREE opcodes have 
run */
@@ -228,6 +232,10 @@ static void zend_generator_clone_storage(zend_generator 
*orig, zend_generator **
);
Z_ADDREF_P(clone-send_target-var.ptr);
}
+
+   if (execute_data-object) {
+   Z_ADDREF_P(execute_data-object);
+   }
}
 
/* The value and key are known not to be references, so simply add refs 
*/


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Add cloning support for generators: Zend/tests/generators/clone.phpt Zend/tests/generators/clone_with_foreach.phpt Zend/tests/generators/clone_with_stack.phpt Zend/tests/generat

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:6117f4c7c0abe3721c2371600a97641003de21a7
Author:Nikita Popov ni...@php.net Sat, 2 Jun 2012 20:40:58 +0200
Parents:   1477be9aa88689f7e547a24258dc4d63637fd5b0
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=6117f4c7c0abe3721c2371600a97641003de21a7

Log:
Add cloning support for generators

Generators can now be cloned. I'm pretty sure that my current code does not
yet cover all the edge cases of cloning the execution context, so there are
probably a few bugs in there :)

Changed paths:
  A  Zend/tests/generators/clone.phpt
  A  Zend/tests/generators/clone_with_foreach.phpt
  A  Zend/tests/generators/clone_with_stack.phpt
  A  Zend/tests/generators/clone_with_symbol_table.phpt
  M  Zend/zend_generators.c

diff --git a/Zend/tests/generators/clone.phpt b/Zend/tests/generators/clone.phpt
new file mode 100644
index 000..94c4c63
--- /dev/null
+++ b/Zend/tests/generators/clone.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Generators can be cloned
+--FILE--
+?php
+
+function *firstN($end) {
+for ($i = 0; $i  $end; ++$i) {
+yield $i;
+}
+}
+
+$g1 = firstN(5);
+var_dump($g1-current());
+$g1-next();
+
+$g2 = clone $g1;
+var_dump($g2-current());
+$g2-next();
+
+var_dump($g2-current());
+var_dump($g1-current());
+
+$g1-next();
+var_dump($g1-current());
+
+?
+--EXPECT--
+int(0)
+int(1)
+int(2)
+int(1)
+int(2)
diff --git a/Zend/tests/generators/clone_with_foreach.phpt 
b/Zend/tests/generators/clone_with_foreach.phpt
new file mode 100644
index 000..42cf334
--- /dev/null
+++ b/Zend/tests/generators/clone_with_foreach.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Cloning a generator with a foreach loop properly adds a ref for the loop var
+--FILE--
+?php
+
+function *gen() {
+foreach ([1, 2, 3] as $i) {
+yield $i;
+}
+}
+
+$g1 = gen();
+var_dump($g1-current());
+
+$g2 = clone $g1;
+var_dump($g2-current());
+
+$g1-next();
+$g2-next();
+var_dump($g1-current());
+var_dump($g2-current());
+
+$g1-close();
+$g2-next();
+var_dump($g2-current());
+
+?
+--EXPECT--
+int(1)
+int(1)
+int(2)
+int(2)
+int(3)
diff --git a/Zend/tests/generators/clone_with_stack.phpt 
b/Zend/tests/generators/clone_with_stack.phpt
new file mode 100644
index 000..79bca31
--- /dev/null
+++ b/Zend/tests/generators/clone_with_stack.phpt
@@ -0,0 +1,18 @@
+--TEST--
+A generator with an active stack can be cloned
+--FILE--
+?php
+
+function *gen() {
+var_dump(str_repeat(x, yield));
+}
+
+$g1 = gen();
+$g1-rewind();
+$g2 = clone $g1;
+$g1-close();
+$g2-send(10);
+
+?
+--EXPECT--
+string(10) xx
diff --git a/Zend/tests/generators/clone_with_symbol_table.phpt 
b/Zend/tests/generators/clone_with_symbol_table.phpt
new file mode 100644
index 000..2a4cf10
--- /dev/null
+++ b/Zend/tests/generators/clone_with_symbol_table.phpt
@@ -0,0 +1,27 @@
+--TEST--
+A generator using a symbol table can be cloned
+--FILE--
+?php
+
+function *gen() {
+// force compiled variable for $foo
+$foo = 'foo';
+
+// force symbol table
+extract(['foo' = 'bar']);
+
+// interrupt
+yield;
+
+var_dump($foo);
+}
+
+$g1 = gen();
+$g1-rewind();
+$g2 = clone $g1;
+$g1-close();
+$g2-next();
+
+?
+--EXPECT--
+string(3) bar
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 5b58e21..01b93ef 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -34,13 +34,7 @@ void zend_generator_close(zend_generator *generator, 
zend_bool finished_executio
if (!execute_data-symbol_table) {
zend_free_compiled_variables(execute_data-CVs, 
execute_data-op_array-last_var);
} else {
-   if (EG(symtable_cache_ptr) = EG(symtable_cache_limit)) 
{
-   zend_hash_destroy(execute_data-symbol_table);
-   FREE_HASHTABLE(execute_data-symbol_table);
-   } else {
-   zend_hash_clean(execute_data-symbol_table);
-   *(++EG(symtable_cache_ptr)) = 
execute_data-symbol_table;
-   }
+   
zend_clean_and_cache_symbol_table(execute_data-symbol_table);
}
 
if (execute_data-current_this) {
@@ -121,6 +115,134 @@ static void zend_generator_free_storage(zend_generator 
*generator TSRMLS_DC) /*
 }
 /* }}} */
 
+static void zend_generator_clone_storage(zend_generator *orig, zend_generator 
**clone_ptr) /* {{{ */
+{
+   zend_generator *clone = emalloc(sizeof(zend_generator));
+   memcpy(clone, orig, sizeof(zend_generator));
+
+   if (orig-execute_data) {
+   /* Create a few shorter aliases to the old execution data */
+   zend_execute_data *execute_data = orig-execute_data;
+   zend_op_array *op_array = execute_data-op_array;
+   HashTable *symbol_table = execute_data-symbol_table;
+
+   /* Alloc separate execution context, as well as separate 
sections for
+

[PHP-CVS] com php-src: Improve backtraces from generators: Zend/tests/generators/backtrace.phpt Zend/zend_generators.c

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:7b3bfa5784cf36647f21a72ceb9741e40927a5b6
Author:Nikita Popov ni...@php.net Sun, 3 Jun 2012 02:00:11 +0200
Parents:   6117f4c7c0abe3721c2371600a97641003de21a7
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=7b3bfa5784cf36647f21a72ceb9741e40927a5b6

Log:
Improve backtraces from generators

The current situation is still not perfect, as the generator function itself
does not appear in the stack trace. This makes sense in some way, but it
would probably be more helpful if it would show up (with the bound arguments)
after the $generator-xyz() call. This could be misleading too though as the
function is not *really* called there.

Changed paths:
  A  Zend/tests/generators/backtrace.phpt
  M  Zend/zend_generators.c


Diff:
diff --git a/Zend/tests/generators/backtrace.phpt 
b/Zend/tests/generators/backtrace.phpt
new file mode 100644
index 000..cbf8de1
--- /dev/null
+++ b/Zend/tests/generators/backtrace.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Printing the stack trace in a generator
+--FILE--
+?php
+
+function f1() {
+debug_print_backtrace();
+}
+
+function *f2() {
+f1();
+}
+
+function f3($gen) {
+$gen-rewind(); // trigger run
+}
+
+$gen = f2();
+f3($gen);
+
+?
+--EXPECTF--
+#0  f1() called at [%s:%d]
+#1  Generator-rewind() called at [%s:%d]
+#2  f3(Generator Object ()) called at [%s:%d]
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 01b93ef..df204fa 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -317,6 +317,10 @@ static void zend_generator_resume(zval *object, 
zend_generator *generator TSRMLS
EG(scope) = generator-execute_data-current_scope;
EG(called_scope) = 
generator-execute_data-current_called_scope;
 
+   /* Set prev_execute_data to the current execute_data to get 
halfways
+* reasonable backtraces */
+   generator-execute_data-prev_execute_data = 
original_execute_data;
+
/* Go to next opcode (we don't want to run the last one again) 
*/
generator-execute_data-opline++;


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Make $generator-send() return the current value: Zend/tests/generators/send_returns_current.phpt Zend/zend_generators.c

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:1477be9aa88689f7e547a24258dc4d63637fd5b0
Author:Nikita Popov ni...@php.net Thu, 31 May 2012 20:03:18 +0200
Parents:   ee89e228f6f684555dd219d8a46d173cfed3230a
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=1477be9aa88689f7e547a24258dc4d63637fd5b0

Log:
Make $generator-send() return the current value

This makes the API easier to use (and is consistent with Python and JS).

Changed paths:
  A  Zend/tests/generators/send_returns_current.phpt
  M  Zend/zend_generators.c


Diff:
diff --git a/Zend/tests/generators/send_returns_current.phpt 
b/Zend/tests/generators/send_returns_current.phpt
new file mode 100644
index 000..d3a4afd
--- /dev/null
+++ b/Zend/tests/generators/send_returns_current.phpt
@@ -0,0 +1,20 @@
+--TEST--
+$generator-send() returns the yielded value
+--FILE--
+?php
+
+function *reverseEchoGenerator() {
+$data = yield;
+while (true) {
+$data = yield strrev($data);
+}
+}
+
+$gen = reverseEchoGenerator();
+var_dump($gen-send('foo'));
+var_dump($gen-send('bar'));
+
+?
+--EXPECT--
+string(3) oof
+string(3) rab
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 4754d75..5b58e21 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -336,7 +336,7 @@ ZEND_METHOD(Generator, next)
 }
 /* }}} */
 
-/* {{{ proto void Generator::send()
+/* {{{ proto mixed Generator::send()
  * Sends a value to the generator */
 ZEND_METHOD(Generator, send)
 {
@@ -366,6 +366,10 @@ ZEND_METHOD(Generator, send)
generator-send_target-var.ptr_ptr = value;
 
zend_generator_resume(object, generator TSRMLS_CC);
+
+   if (generator-value) {
+   RETURN_ZVAL(generator-value, 1, 0);
+   }
 }
 
 /* {{{ proto void Generator::close()


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Allow throwing exceptions from generators: Zend/tests/generators/generator_throwing_exception.phpt Zend/zend_vm_def.h Zend/zend_vm_execute.h

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:0033a525213e68e6ae74b3c3d75fd6ea4beea5d6
Author:Nikita Popov ni...@php.net Wed, 30 May 2012 16:28:33 +0200
Parents:   879016023566ce162be1d81e973bde9db76dd519
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=0033a525213e68e6ae74b3c3d75fd6ea4beea5d6

Log:
Allow throwing exceptions from generators

The missing piece is how one can find the next stack frame, which is
required for dtor'ing arguments pushed to the stack. As the generator
execute_data does not live on the stack one can't use it to figure out the
start of the next stack frame. So there must be some other method.

Changed paths:
  A  Zend/tests/generators/generator_throwing_exception.phpt
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h

diff --git a/Zend/tests/generators/generator_throwing_exception.phpt 
b/Zend/tests/generators/generator_throwing_exception.phpt
new file mode 100644
index 000..5df4a81
--- /dev/null
+++ b/Zend/tests/generators/generator_throwing_exception.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Generators can throw exceptions
+--FILE--
+?php
+
+function *gen() {
+yield 'foo';
+throw new Exception('test');
+yield 'bar';
+}
+
+$gen = gen();
+
+var_dump($gen-current());
+
+try {
+$gen-next();
+} catch (Exception $e) {
+echo 'Caught exception with message ', $e-getMessage(), '', \n;
+}
+
+var_dump($gen-current());
+
+?
+--EXPECT--
+string(3) foo
+Caught exception with message test
+NULL
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index f1fd64c..cbdf701 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2821,10 +2821,10 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
/* The generator object is stored in return_value_ptr_ptr */
zend_generator *generator = (zend_generator *) 
zend_object_store_get_object(*EG(return_value_ptr_ptr) TSRMLS_CC);
 
-   /* Close the generator to free up resources. */
+   /* Close the generator to free up resources */
zend_generator_close(generator, 1 TSRMLS_CC);
 
-   /* Pass execution back to generator handling code */
+   /* Pass execution back to handling code */
ZEND_VM_RETURN();
}
 
@@ -4992,11 +4992,25 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
int i;
zend_uint catch_op_num = 0;
int catched = 0;
-   zval restored_error_reporting;
+   void **stack_frame;
 
-   void **stack_frame = (void**)(((char*)EX_Ts()) +
-   (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * 
EX(op_array)-T));
+   /* Figure out where the next stack frame (which maybe contains pushed
+* arguments that have to be dtor'ed) starts */
+   if (EX(op_array)-fn_flags  ZEND_ACC_GENERATOR) {
+   /* For generators the execution context is not stored on the 
stack so
+* I don't know yet how to figure out where the next stack frame
+* starts. For now I'll just use the stack top to ignore 
argument
+* dtor'ing altogether. */
+   stack_frame = zend_vm_stack_top(TSRMLS_C);
+   } else {
+   /* In all other cases the next stack frame starts after the 
temporary
+* variables section of the current execution context */
+   stack_frame = (void **) ((char *) EX_Ts() +
+   ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * 
EX(op_array)-T);
+   }
 
+   /* If the exception was thrown during a function call there might be
+* arguments pushed to the stack that have to be dtor'ed. */
while (zend_vm_stack_top(TSRMLS_C) != stack_frame) {
zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
zval_ptr_dtor(stack_zval_p);
@@ -5058,6 +5072,8 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
 
/* restore previous error_reporting value */
if (!EG(error_reporting)  EX(old_error_reporting) != NULL  
Z_LVAL_P(EX(old_error_reporting)) != 0) {
+   zval restored_error_reporting;
+
Z_TYPE(restored_error_reporting) = IS_LONG;
Z_LVAL(restored_error_reporting) = 
Z_LVAL_P(EX(old_error_reporting));
convert_to_string(restored_error_reporting);
@@ -5067,6 +5083,18 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
EX(old_error_reporting) = NULL;
 
if (!catched) {
+   /* For generators skip the leave handler return directly */
+   if (EX(op_array)-fn_flags  ZEND_ACC_GENERATOR) {
+   /* The generator object is stored in 
return_value_ptr_ptr */
+   zend_generator *generator = (zend_generator *) 
zend_object_store_get_object(*EG(return_value_ptr_ptr) TSRMLS_CC);
+
+   /* Close the generator to free up resources */
+   zend_generator_close(generator, 1 TSRMLS_CC);
+
+   /* Pass execution 

[PHP-CVS] com php-src: Add auto-increment keys: Zend/tests/generators/auto_incrementing_keys.phpt Zend/zend_generators.c Zend/zend_generators.h Zend/zend_vm_def.h Zend/zend_vm_execute.h

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:879016023566ce162be1d81e973bde9db76dd519
Author:Nikita Popov ni...@php.net Wed, 30 May 2012 05:05:49 +0200
Parents:   bc08c2cf9485e20fea0eef7ab149cefdf9a3662e
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=879016023566ce162be1d81e973bde9db76dd519

Log:
Add auto-increment keys

When no key is explicitely yielded PHP will used auto-incrementing keys
as a fallback. They behave the same as with arrays, i.e. the key is the
successor of the largest previously used integer key.

Changed paths:
  A  Zend/tests/generators/auto_incrementing_keys.phpt
  M  Zend/zend_generators.c
  M  Zend/zend_generators.h
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h

diff --git a/Zend/tests/generators/auto_incrementing_keys.phpt 
b/Zend/tests/generators/auto_incrementing_keys.phpt
new file mode 100644
index 000..623f2d8
--- /dev/null
+++ b/Zend/tests/generators/auto_incrementing_keys.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Generator keys are auto-incrementing by default
+--FILE--
+?php
+
+function *gen() {
+yield 'foo';
+yield 'bar';
+yield 5 = 'rab';
+yield 'oof';
+}
+
+foreach (gen() as $k = $v) {
+echo $k, ' = ', $v, \n;
+}
+
+?
+--EXPECT--
+0 = foo
+1 = bar
+5 = rab
+6 = oof
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index d3d4b3f..5c211b0 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -116,6 +116,9 @@ static zend_object_value 
zend_generator_create(zend_class_entry *class_type TSRM
generator = emalloc(sizeof(zend_generator));
memset(generator, 0, sizeof(zend_generator));
 
+   /* The key will be incremented on first use, so it'll start at 0 */
+   generator-largest_used_integer_key = -1;
+
zend_object_std_init(generator-std, class_type TSRMLS_CC);
 
object.handle = zend_objects_store_put(generator, NULL,
diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h
index 2fd2c93..b73557c 100644
--- a/Zend/zend_generators.h
+++ b/Zend/zend_generators.h
@@ -34,6 +34,8 @@ typedef struct _zend_generator {
zval *key;
/* Variable to put sent value into */
temp_variable *send_target;
+   /* Largest used integer key for auto-incrementing keys */
+   long largest_used_integer_key;
 } zend_generator;
 
 extern ZEND_API zend_class_entry *zend_ce_generator;
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 36b9c93..f1fd64c 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -5332,11 +5332,19 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, 
CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
generator-key = key;
}
 
+   if (Z_TYPE_P(generator-key) == IS_LONG
+Z_LVAL_P(generator-key)  
generator-largest_used_integer_key
+   ) {
+   generator-largest_used_integer_key = 
Z_LVAL_P(generator-key);
+   }
+
FREE_OP2_IF_VAR();
} else {
-   /* Setting the key to NULL signals that the auto-increment key
-* generation should be used */
-   generator-key = NULL;
+   /* If no key was specified we use auto-increment keys */
+   generator-largest_used_integer_key++;
+
+   ALLOC_INIT_ZVAL(generator-key);
+   ZVAL_LONG(generator-key, generator-largest_used_integer_key);
}
 
/* If a value is sent it should go into the result var */
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index ac7ff7f..09c3461 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -4127,10 +4127,18 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE
generator-key = key;
}
 
+   if (Z_TYPE_P(generator-key) == IS_LONG
+Z_LVAL_P(generator-key)  
generator-largest_used_integer_key
+   ) {
+   generator-largest_used_integer_key = 
Z_LVAL_P(generator-key);
+   }
+
} else {
-   /* Setting the key to NULL signals that the auto-increment key
-* generation should be used */
-   generator-key = NULL;
+   /* If no key was specified we use auto-increment keys */
+   generator-largest_used_integer_key++;
+
+   ALLOC_INIT_ZVAL(generator-key);
+   ZVAL_LONG(generator-key, generator-largest_used_integer_key);
}
 
/* If a value is sent it should go into the result var */
@@ -4760,10 +4768,18 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_
generator-key = key;
}
 
+   if (Z_TYPE_P(generator-key) == IS_LONG
+Z_LVAL_P(generator-key)  
generator-largest_used_integer_key
+   ) {
+   generator-largest_used_integer_key = 
Z_LVAL_P(generator-key);
+ 

[PHP-CVS] com php-src: Add $generator-close() method: Zend/tests/generators/generator_close.phpt Zend/zend_generators.c

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:72a91d08e7d70d5524feb6cc7c8e32b3bd68f1df
Author:Nikita Popov ni...@php.net Tue, 29 May 2012 18:11:18 +0200
Parents:   12e928314fb270db31adc361ac4993b4f0fe000a
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=72a91d08e7d70d5524feb6cc7c8e32b3bd68f1df

Log:
Add $generator-close() method

Calling $generator-close() is equivalent to executing a return statement
at the current position in the generator.

Changed paths:
  A  Zend/tests/generators/generator_close.phpt
  M  Zend/zend_generators.c


Diff:
diff --git a/Zend/tests/generators/generator_close.phpt 
b/Zend/tests/generators/generator_close.phpt
new file mode 100644
index 000..003eef0
--- /dev/null
+++ b/Zend/tests/generators/generator_close.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Generator can be closed by calling -close()
+--FILE--
+?php
+
+function *allNumbers() {
+for ($i = 0; true; ++$i) {
+yield $i;
+}
+}
+
+$numbers = allNumbers();
+
+foreach ($numbers as $n) {
+var_dump($n);
+if ($n == 9) {
+$numbers-close();
+}
+}
+
+?
+--EXPECT--
+int(0)
+int(1)
+int(2)
+int(3)
+int(4)
+int(5)
+int(6)
+int(7)
+int(8)
+int(9)
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 0cf600a..b2fe8af 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -324,6 +324,22 @@ ZEND_METHOD(Generator, send)
zend_generator_resume(object, generator TSRMLS_CC);
 }
 
+/* {{{ proto void Generator::close()
+ * Closes the generator */
+ZEND_METHOD(Generator, close)
+{
+   zend_generator *generator;
+
+   if (zend_parse_parameters_none() == FAILURE) {
+   return;
+   }
+
+   generator = (zend_generator *) zend_object_store_get_object(getThis() 
TSRMLS_CC);
+
+   zend_generator_close(generator, 0);
+}
+/* }}} */
+
 ZEND_BEGIN_ARG_INFO(arginfo_generator_void, 0)
 ZEND_END_ARG_INFO()
 
@@ -338,6 +354,7 @@ static const zend_function_entry generator_functions[] = {
ZEND_ME(Generator, key, arginfo_generator_void, ZEND_ACC_PUBLIC)
ZEND_ME(Generator, next,arginfo_generator_void, ZEND_ACC_PUBLIC)
ZEND_ME(Generator, send,arginfo_generator_send, ZEND_ACC_PUBLIC)
+   ZEND_ME(Generator, close,   arginfo_generator_void, ZEND_ACC_PUBLIC)
ZEND_FE_END
 };


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Allow to use yield without value: Zend/tests/generators/yield_without_value.phpt Zend/zend_compile.c Zend/zend_language_parser.y Zend/zend_vm_def.h Zend/zend_vm_execute.h

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:ad525c288ad83df497ed1a0668915cad61d72e26
Author:Nikita Popov ni...@php.net Tue, 29 May 2012 17:53:11 +0200
Parents:   3600914ced52eb4f6db10410ba887c8e2a2acfe1
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=ad525c288ad83df497ed1a0668915cad61d72e26

Log:
Allow to use yield without value

If the generator is used as a coroutine it often doesn't make sense to yield
anything. In this case one can simply receive values using

$value = yield;

The yield here will simply yield NULL.

Changed paths:
  A  Zend/tests/generators/yield_without_value.phpt
  M  Zend/zend_compile.c
  M  Zend/zend_language_parser.y
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h

diff --git a/Zend/tests/generators/yield_without_value.phpt 
b/Zend/tests/generators/yield_without_value.phpt
new file mode 100644
index 000..dc467a8
--- /dev/null
+++ b/Zend/tests/generators/yield_without_value.phpt
@@ -0,0 +1,27 @@
+--TEST--
+yield can be used without a value
+--FILE--
+?php
+
+function *recv() {
+while (true) {
+var_dump(yield);
+}
+}
+
+$reciever = recv();
+var_dump($reciever-current());
+$reciever-send(1);
+var_dump($reciever-current());
+$reciever-send(2);
+var_dump($reciever-current());
+$reciever-send(3);
+
+?
+--EXPECT--
+NULL
+int(1)
+NULL
+int(2)
+NULL
+int(3)
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 37e4901..89549bb 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2673,8 +2673,12 @@ void zend_do_yield(znode *result, const znode *expr 
TSRMLS_DC) /* {{{ */
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 
opline-opcode = ZEND_YIELD;
-   SET_NODE(opline-op1, expr);
-   SET_UNUSED(opline-op2);
+
+   if (expr) {
+   SET_NODE(opline-op1, expr);
+   } else {
+   SET_UNUSED(opline-op2);
+   }
 
opline-result_type = IS_VAR;
opline-result.var = get_temporary_variable(CG(active_op_array));
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index ea8ac41..ac22e7f 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -801,6 +801,7 @@ expr_without_variable:
|   combined_scalar { $$ = $1; }
|   '`' backticks_expr '`' { zend_do_shell_exec($$, $2 
TSRMLS_CC); }
|   T_PRINT expr  { zend_do_print($$, $2 TSRMLS_CC); }
+   |   T_YIELD { zend_do_yield($$, NULL TSRMLS_CC); }
|   T_YIELD expr { zend_do_yield($$, $2 TSRMLS_CC); }
|   function is_generator is_reference { 
zend_do_begin_lambda_function_declaration($$, $1, $2.op_type, $3.op_type, 0 
TSRMLS_CC); }
'(' parameter_list ')' lexical_vars { 
zend_do_suspend_if_generator(TSRMLS_C); }
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 8c810cd..6761030 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -5258,7 +5258,7 @@ ZEND_VM_HANDLER(159, ZEND_SUSPEND_AND_RETURN_GENERATOR, 
ANY, ANY)
ZEND_VM_RETURN();
 }
 
-ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV, ANY)
+ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, ANY)
 {
USE_OPLINE
 
@@ -5271,7 +5271,7 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV, ANY)
}
 
/* Set the new yielded value */
-   {
+   if (OP1_TYPE != IS_UNUSED) {
zend_free_op free_op1;
zval *value = GET_OP1_ZVAL_PTR(BP_VAR_R);
 
@@ -5291,11 +5291,15 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV, ANY)
 
generator-value = copy;
} else {
-   generator-value = value;
Z_ADDREF_P(value);
+   generator-value = value;
}
 
FREE_OP1_IF_VAR();
+   } else {
+   /* If no value way specified yield null */
+   Z_ADDREF(EG(uninitialized_zval));
+   generator-value = EG(uninitialized_zval);
}
 
/* If a value is sent it should go into the result var */
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index fa07733..efe0812 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -3047,7 +3047,7 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
}
 
/* Set the new yielded value */
-   {
+   if (IS_CONST != IS_UNUSED) {
 
zval *value = opline-op1.zv;
 
@@ -3067,10 +3067,14 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
 
generator-value = copy;
} else {
-   generator-value = value;
Z_ADDREF_P(value);
+   generator-value = value;
}
 
+   } else {
+   /* If no value way specified yield null */
+   Z_ADDREF(EG(uninitialized_zval));
+   generator-value = EG(uninitialized_zval);
}
 
/* If 

[PHP-CVS] com php-src: Fix segfault when send()ing to a closed generator: Zend/tests/generators/send_after_close.phpt Zend/zend_generators.c

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:12e928314fb270db31adc361ac4993b4f0fe000a
Author:Nikita Popov ni...@php.net Tue, 29 May 2012 18:01:08 +0200
Parents:   ad525c288ad83df497ed1a0668915cad61d72e26
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=12e928314fb270db31adc361ac4993b4f0fe000a

Log:
Fix segfault when send()ing to a closed generator

Changed paths:
  A  Zend/tests/generators/send_after_close.phpt
  M  Zend/zend_generators.c


Diff:
diff --git a/Zend/tests/generators/send_after_close.phpt 
b/Zend/tests/generators/send_after_close.phpt
new file mode 100644
index 000..6a251b2
--- /dev/null
+++ b/Zend/tests/generators/send_after_close.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Calls to send() after close should do nothing
+--FILE--
+?php
+
+function *gen() { }
+
+$gen = gen();
+$gen-send(Test);
+
+?
+===DONE===
+--EXPECT--
+===DONE===
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 01c9aa3..0cf600a 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -308,6 +308,11 @@ ZEND_METHOD(Generator, send)
 
zend_generator_ensure_initialized(object, generator TSRMLS_CC); 
 
+   /* The generator is already closed, thus can't send anything */
+   if (!generator-execute_data) {
+   return;
+   }
+
/* The sent value was initialized to NULL, so dtor that */
zval_ptr_dtor(generator-send_target-var.ptr_ptr);


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Add support for $generator-send(): Zend/tests/generators/generator_send.phpt Zend/zend_compile.c Zend/zend_compile.h Zend/zend_generators.c Zend/zend_generators.h Zend/zend_lan

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:3600914ced52eb4f6db10410ba887c8e2a2acfe1
Author:Nikita Popov ni...@php.net Tue, 29 May 2012 17:34:33 +0200
Parents:   b770b221e0b3036708deb9e22dacf296402787f0
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=3600914ced52eb4f6db10410ba887c8e2a2acfe1

Log:
Add support for $generator-send()

Yield now is an expression and the return value is the value passed to
$generator-send(). By default (i.e. if -next() is called) the value is
NULL.

Unlike in Python -send() can be run without priming the generator with a
-next() call first.

Changed paths:
  A  Zend/tests/generators/generator_send.phpt
  M  Zend/zend_compile.c
  M  Zend/zend_compile.h
  M  Zend/zend_generators.c
  M  Zend/zend_generators.h
  M  Zend/zend_language_parser.y
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h

diff --git a/Zend/tests/generators/generator_send.phpt 
b/Zend/tests/generators/generator_send.phpt
new file mode 100644
index 000..11ac37f
--- /dev/null
+++ b/Zend/tests/generators/generator_send.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Values can be sent back to the generator
+--FILE--
+?php
+
+function *gen() {
+var_dump(yield yield foo);
+var_dump(yield yield bar);
+}
+
+$gen = gen();
+var_dump($gen-current());
+$gen-send(send bar);
+var_dump($gen-current());
+$gen-send(send foo);
+
+?
+--EXPECT--
+string(9) yield foo
+string(8) send bar
+string(9) yield bar
+string(8) send foo
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 30fecf1..37e4901 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2662,7 +2662,7 @@ void zend_do_return(znode *expr, int do_end_vparse 
TSRMLS_DC) /* {{{ */
 }
 /* }}} */
 
-void zend_do_yield(znode *expr TSRMLS_DC) /* {{{ */
+void zend_do_yield(znode *result, const znode *expr TSRMLS_DC) /* {{{ */
 {
zend_op *opline;
 
@@ -2675,6 +2675,10 @@ void zend_do_yield(znode *expr TSRMLS_DC) /* {{{ */
opline-opcode = ZEND_YIELD;
SET_NODE(opline-op1, expr);
SET_UNUSED(opline-op2);
+
+   opline-result_type = IS_VAR;
+   opline-result.var = get_temporary_variable(CG(active_op_array));
+   GET_NODE(result, opline-result);
 }
 /* }}} */
 
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 5365f96..953a9f1 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -490,7 +490,7 @@ void zend_do_build_full_name(znode *result, znode *prefix, 
znode *name, int is_c
 int zend_do_begin_class_member_function_call(znode *class_name, znode 
*method_name TSRMLS_DC);
 void zend_do_end_function_call(znode *function_name, znode *result, const 
znode *argument_list, int is_method, int is_dynamic_fcall TSRMLS_DC);
 void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC);
-void zend_do_yield(znode *expr TSRMLS_DC);
+void zend_do_yield(znode *result, const znode *expr TSRMLS_DC);
 void zend_do_suspend_if_generator(TSRMLS_D);
 void zend_do_handle_exception(TSRMLS_D);
 
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index e4b0704..01c9aa3 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -292,15 +292,47 @@ ZEND_METHOD(Generator, next)
 }
 /* }}} */
 
+/* {{{ proto void Generator::send()
+ * Sends a value to the generator */
+ZEND_METHOD(Generator, send)
+{
+   zval *object, *value;
+   zend_generator *generator;
+
+   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, z, value) == 
FAILURE) {
+   return;
+   }
+
+   object = getThis();
+   generator = (zend_generator *) zend_object_store_get_object(object 
TSRMLS_CC);
+
+   zend_generator_ensure_initialized(object, generator TSRMLS_CC); 
+
+   /* The sent value was initialized to NULL, so dtor that */
+   zval_ptr_dtor(generator-send_target-var.ptr_ptr);
+
+   /* Set new sent value */
+   Z_ADDREF_P(value);
+   generator-send_target-var.ptr = value;
+   generator-send_target-var.ptr_ptr = value;
+
+   zend_generator_resume(object, generator TSRMLS_CC);
+}
+
 ZEND_BEGIN_ARG_INFO(arginfo_generator_void, 0)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_generator_send, 0, 0, 1)
+   ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
 static const zend_function_entry generator_functions[] = {
ZEND_ME(Generator, rewind,  arginfo_generator_void, ZEND_ACC_PUBLIC)
ZEND_ME(Generator, valid,   arginfo_generator_void, ZEND_ACC_PUBLIC)
ZEND_ME(Generator, current, arginfo_generator_void, ZEND_ACC_PUBLIC)
ZEND_ME(Generator, key, arginfo_generator_void, ZEND_ACC_PUBLIC)
ZEND_ME(Generator, next,arginfo_generator_void, ZEND_ACC_PUBLIC)
+   ZEND_ME(Generator, send,arginfo_generator_send, ZEND_ACC_PUBLIC)
ZEND_FE_END
 };
 
diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h
index 192e9e7..c9b43b3 100644
--- a/Zend/zend_generators.h
+++ b/Zend/zend_generators.h
@@ -30,6 +30,8 @@ typedef struct _zend_generator {
zend_execute_data *execute_data;
/* Current value */

[PHP-CVS] com php-src: Set EG(current_execute_data): Zend/tests/generators/generator_method.phpt Zend/zend_generators.c

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:bcc7d976f31a572160a52c15f415deea3497ab68
Author:Nikita Popov ni...@php.net Mon, 28 May 2012 00:24:58 +0200
Parents:   9f52c5c22647f0648dbb350c551417b1ad070359
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=bcc7d976f31a572160a52c15f415deea3497ab68

Log:
Set EG(current_execute_data)

This fixes several issues. In particular it makes method generators work
properly and also allows generators using a symbol table.

Changed paths:
  A  Zend/tests/generators/generator_method.phpt
  M  Zend/zend_generators.c


Diff:
diff --git a/Zend/tests/generators/generator_method.phpt 
b/Zend/tests/generators/generator_method.phpt
new file mode 100644
index 000..b64476d
--- /dev/null
+++ b/Zend/tests/generators/generator_method.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Methods can be generators
+--FILE--
+?php
+
+class Test implements IteratorAggregate {
+protected $data;
+
+public function __construct(array $data) {
+$this-data = $data;
+}
+
+public function *getIterator() {
+foreach ($this-data as $value) {
+yield $value;
+}
+}
+}
+
+$test = new Test(['foo', 'bar', 'baz']);
+foreach ($test as $value) {
+var_dump($value);
+}
+
+?
+--EXPECT--
+string(3) foo
+string(3) bar
+string(3) baz
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 12116a0..00d637c 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -148,6 +148,7 @@ static void zend_generator_resume(zval *object, 
zend_generator *generator TSRMLS
{
/* Backup executor globals */
zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
+   zend_execute_data *original_execute_data = 
EG(current_execute_data);
zend_op **original_opline_ptr = EG(opline_ptr);
zend_op_array *original_active_op_array = EG(active_op_array);
HashTable *original_active_symbol_table = 
EG(active_symbol_table);
@@ -160,6 +161,7 @@ static void zend_generator_resume(zval *object, 
zend_generator *generator TSRMLS
EG(return_value_ptr_ptr) = object;
 
/* Set executor globals */
+   EG(current_execute_data) = generator-execute_data;
EG(opline_ptr) = generator-execute_data-opline;
EG(active_op_array) = generator-execute_data-op_array;
EG(active_symbol_table) = generator-execute_data-symbol_table;
@@ -175,6 +177,7 @@ static void zend_generator_resume(zval *object, 
zend_generator *generator TSRMLS
 
/* Restore executor globals */
EG(return_value_ptr_ptr) = original_return_value_ptr_ptr;
+   EG(current_execute_data) = original_execute_data;
EG(opline_ptr) = original_opline_ptr;
EG(active_op_array) = original_active_op_array;
EG(active_symbol_table) = original_active_symbol_table;


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Add support for generator methods: Zend/zend_generators.c Zend/zend_vm_def.h Zend/zend_vm_execute.h

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:247bb737d552508829c5de7770ed0b15c3d8f7fd
Author:Nikita Popov ni...@php.net Sun, 27 May 2012 03:50:31 +0200
Parents:   39d3d5ec138119acf614fb285e92c3bcda7a2555
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=247bb737d552508829c5de7770ed0b15c3d8f7fd

Log:
Add support for generator methods

Changed paths:
  M  Zend/zend_generators.c
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h


Diff:
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 36a9727..ae706f1 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -48,6 +48,10 @@ void zend_generator_close(zend_generator *generator 
TSRMLS_DC) /* {{{ */
}
}
 
+   if (execute_data-current_this) {
+   zval_ptr_dtor(execute_data-current_this);
+   }
+
efree(execute_data);
generator-execute_data = NULL;
}
@@ -105,28 +109,43 @@ static void zend_generator_resume(zval *object, 
zend_generator *generator TSRMLS
return;
}
 
-   /* Backup executor globals */
-   zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
-   zend_op **original_opline_ptr = EG(opline_ptr);
-   zend_op_array *original_active_op_array = EG(active_op_array);
-
-   /* We (mis) use the return_value_ptr_ptr to provide the generator object
-* to the executor. This way YIELD will be able to set the yielded 
value */
-   EG(return_value_ptr_ptr) = object;
-
-   EG(opline_ptr) = generator-execute_data-opline;
-   EG(active_op_array) = generator-execute_data-op_array;
-
-   /* Go to next opcode (we don't want to run the last one again) */
-   generator-execute_data-opline++;
-
-   /* Resume execution */
-   execute_ex(generator-execute_data TSRMLS_CC);
-
-   /* Restore executor globals */
-   EG(return_value_ptr_ptr) = original_return_value_ptr_ptr;
-   EG(opline_ptr) = original_opline_ptr;
-   EG(active_op_array) = original_active_op_array;
+   {
+   /* Backup executor globals */
+   zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
+   zend_op **original_opline_ptr = EG(opline_ptr);
+   zend_op_array *original_active_op_array = EG(active_op_array);
+   HashTable *original_active_symbol_table = 
EG(active_symbol_table);
+   zval *original_This = EG(This);
+   zend_class_entry *original_scope = EG(scope);
+   zend_class_entry *original_called_scope = EG(called_scope);
+
+   /* We (mis)use the return_value_ptr_ptr to provide the 
generator object
+* to the executor, so YIELD will be able to set the yielded 
value */
+   EG(return_value_ptr_ptr) = object;
+
+   /* Set executor globals */
+   EG(opline_ptr) = generator-execute_data-opline;
+   EG(active_op_array) = generator-execute_data-op_array;
+   EG(active_symbol_table) = generator-execute_data-symbol_table;
+   EG(This) = generator-execute_data-current_this;
+   EG(scope) = generator-execute_data-current_scope;
+   EG(called_scope) = 
generator-execute_data-current_called_scope;
+
+   /* Go to next opcode (we don't want to run the last one again) 
*/
+   generator-execute_data-opline++;
+
+   /* Resume execution */
+   execute_ex(generator-execute_data TSRMLS_CC);
+
+   /* Restore executor globals */
+   EG(return_value_ptr_ptr) = original_return_value_ptr_ptr;
+   EG(opline_ptr) = original_opline_ptr;
+   EG(active_op_array) = original_active_op_array;
+   EG(active_symbol_table) = original_active_symbol_table;
+   EG(This) = original_This;
+   EG(scope) = original_scope;
+   EG(called_scope) = original_called_scope;
+   }
 }
 /* }}} */
 
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 781bd9f..42397ed 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -5225,6 +5225,11 @@ ZEND_VM_HANDLER(159, ZEND_SUSPEND_AND_RETURN_GENERATOR, 
ANY, ANY)
 
*EG(return_value_ptr_ptr) = return_value;
 
+   /* back up some executor globals */
+   EX(current_this) = EG(This);
+   EX(current_scope) = EG(scope);
+   EX(current_called_scope) = EG(called_scope);
+
/* back up the execution context */
generator = (zend_generator *) 
zend_object_store_get_object(return_value TSRMLS_CC);
generator-execute_data = execute_data;
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 1eac105..fa802c6 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -1207,6 +1207,11 @@ static int ZEND_FASTCALL  

[PHP-CVS] com php-src: Fix generator creation when execute_data is not nested: Zend/tests/generators/dynamic_call.phpt Zend/zend_vm_def.h Zend/zend_vm_execute.h

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:9f52c5c22647f0648dbb350c551417b1ad070359
Author:Nikita Popov ni...@php.net Sun, 27 May 2012 22:48:21 +0200
Parents:   64a643a4e3c1b45d3a9b2ad24537f7aab6296f7d
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=9f52c5c22647f0648dbb350c551417b1ad070359

Log:
Fix generator creation when execute_data is not nested

This happens primarily when the generator is invoked from some internal
place like a dynamic function call.

Changed paths:
  A  Zend/tests/generators/dynamic_call.phpt
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h


Diff:
diff --git a/Zend/tests/generators/dynamic_call.phpt 
b/Zend/tests/generators/dynamic_call.phpt
new file mode 100644
index 000..7b4b0c3
--- /dev/null
+++ b/Zend/tests/generators/dynamic_call.phpt
@@ -0,0 +1,19 @@
+--TEST--
+It's possible to invoke a generator dynamically
+--FILE--
+?php
+
+function *gen($foo, $bar) {
+yield $foo;
+yield $bar;
+}
+
+$gen = call_user_func('gen', 'bar', 'foo');
+foreach ($gen as $value) {
+var_dump($value);
+}
+
+?
+--EXPECT--
+string(3) bar
+string(3) foo
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 440b36d..0b06c92 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -5265,10 +5265,12 @@ ZEND_VM_HANDLER(159, ZEND_SUSPEND_AND_RETURN_GENERATOR, 
ANY, ANY)
EX(called_scope) = DECODE_CTOR(EX(called_scope));
 
zend_vm_stack_clear_multiple(TSRMLS_C);
+
+   ZEND_VM_INC_OPCODE();
+   ZEND_VM_LEAVE();
}
 
-   ZEND_VM_INC_OPCODE();
-   ZEND_VM_LEAVE();
+   ZEND_VM_RETURN();
 }
 
 ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV, ANY)
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 8f06afa..6879d9d 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -1247,10 +1247,12 @@ static int ZEND_FASTCALL  
ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER(ZEND_OP
EX(called_scope) = DECODE_CTOR(EX(called_scope));
 
zend_vm_stack_clear_multiple(TSRMLS_C);
+
+   ZEND_VM_INC_OPCODE();
+   ZEND_VM_LEAVE();
}
 
-   ZEND_VM_INC_OPCODE();
-   ZEND_VM_LEAVE();
+   ZEND_VM_RETURN();
 }
 
 static int ZEND_FASTCALL  
ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Add first real generator test: Zend/tests/generators/xrange.phpt

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:39d3d5ec138119acf614fb285e92c3bcda7a2555
Author:Nikita Popov ni...@php.net Sun, 27 May 2012 00:50:27 +0200
Parents:   cbfa96cad59d679502eca002a1e920065f11f871
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=39d3d5ec138119acf614fb285e92c3bcda7a2555

Log:
Add first real generator test

The test implements an xrange() function (the generator version of range()).

Changed paths:
  A  Zend/tests/generators/xrange.phpt


Diff:
diff --git a/Zend/tests/generators/xrange.phpt 
b/Zend/tests/generators/xrange.phpt
new file mode 100644
index 000..685c6b3
--- /dev/null
+++ b/Zend/tests/generators/xrange.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Simple generator xrange() test
+--FILE--
+?php
+
+function *xrange($start, $end, $step = 1) {
+   for ($i = $start; $i = $end; $i += $step) {
+   yield $i;
+   }
+}
+
+foreach (xrange(10, 20, 2) as $i) {
+   var_dump($i);
+}
+
+?
+--EXPECT--
+int(10)
+int(12)
+int(14)
+int(16)
+int(18)
+int(20)


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Make the GOTO and SWITCH VMs work again: Zend/zend_vm_def.h Zend/zend_vm_execute.h Zend/zend_vm_execute.skl Zend/zend_vm_gen.php

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:b770b221e0b3036708deb9e22dacf296402787f0
Author:Nikita Popov ni...@php.net Tue, 29 May 2012 02:31:56 +0200
Parents:   4aab08b64c2318775be6d8e629747ac66a108485
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=b770b221e0b3036708deb9e22dacf296402787f0

Log:
Make the GOTO and SWITCH VMs work again

Changed paths:
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h
  M  Zend/zend_vm_execute.skl
  M  Zend/zend_vm_gen.php

diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 04b6595..47d5ec4 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -5203,6 +5203,7 @@ ZEND_VM_HANDLER(159, ZEND_SUSPEND_AND_RETURN_GENERATOR, 
ANY, ANY)
*EG(return_value_ptr_ptr) = return_value;
 
/* back up some executor globals */
+   SAVE_OPLINE();
EX(current_this) = EG(This);
EX(current_scope) = EG(scope);
EX(current_called_scope) = EG(called_scope);
@@ -5248,6 +5249,8 @@ ZEND_VM_HANDLER(159, ZEND_SUSPEND_AND_RETURN_GENERATOR, 
ANY, ANY)
 
zend_vm_stack_clear_multiple(TSRMLS_C);
 
+   LOAD_REGS();
+   LOAD_OPLINE();
ZEND_VM_INC_OPCODE();
ZEND_VM_LEAVE();
}
@@ -5293,6 +5296,10 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV, ANY)
FREE_OP1_IF_VAR();
}
 
+   /* The GOTO VM uses a local opline variable. We need to set the opline
+* variable in execute_data so we don't resume at an old position. */
+   SAVE_OPLINE();
+
ZEND_VM_RETURN();
 }
 
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index c195148..bd22768 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -393,10 +393,10 @@ static zend_execute_data 
*zend_create_execute_data_from_op_array(zend_op_array *
if (op_array-this_var != -1  EG(This)) {
Z_ADDREF_P(EG(This)); /* For $this pointer */
if (!EG(active_symbol_table)) {
-   EX_CV(op_array-this_var) = (zval**)EX_CVs() + 
(op_array-last_var + op_array-this_var);
-   *EX_CV(op_array-this_var) = EG(This);
+   EX(CVs)[op_array-this_var] = (zval **) EX(CVs) + 
op_array-last_var + op_array-this_var;
+   *EX(CVs)[op_array-this_var] = EG(This);
} else {
-   if (zend_hash_add(EG(active_symbol_table), this, 
sizeof(this), EG(This), sizeof(zval *), 
(void**)EX_CV(op_array-this_var))==FAILURE) {
+   if (zend_hash_add(EG(active_symbol_table), this, 
sizeof(this), EG(This), sizeof(zval *), (void **) 
EX(CVs)[op_array-this_var])==FAILURE) {
Z_DELREF_P(EG(This));
}
}
@@ -425,7 +425,6 @@ ZEND_API void execute_ex(zend_execute_data *execute_data 
TSRMLS_DC)
 
EG(in_execution) = 1;
 
-zend_vm_enter:
LOAD_REGS();
LOAD_OPLINE();
 
@@ -444,8 +443,10 @@ zend_vm_enter:
return;
case 2:
execute_data = 
zend_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC);
+   break;
case 3:
execute_data = EG(current_execute_data);
+   break;
default:
break;
}
@@ -1185,6 +1186,7 @@ static int ZEND_FASTCALL  
ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER(ZEND_OP
*EG(return_value_ptr_ptr) = return_value;
 
/* back up some executor globals */
+   SAVE_OPLINE();
EX(current_this) = EG(This);
EX(current_scope) = EG(scope);
EX(current_called_scope) = EG(called_scope);
@@ -1230,6 +1232,8 @@ static int ZEND_FASTCALL  
ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER(ZEND_OP
 
zend_vm_stack_clear_multiple(TSRMLS_C);
 
+   LOAD_REGS();
+   LOAD_OPLINE();
ZEND_VM_INC_OPCODE();
ZEND_VM_LEAVE();
}
@@ -3067,6 +3071,10 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
 
}
 
+   /* The GOTO VM uses a local opline variable. We need to set the opline
+* variable in execute_data so we don't resume at an old position. */
+   SAVE_OPLINE();
+
ZEND_VM_RETURN();
 }
 
@@ -7704,6 +7712,10 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
}
 
+   /* The GOTO VM uses a local opline variable. We need to set the opline
+* variable in execute_data so we don't resume at an old position. */
+   SAVE_OPLINE();
+
ZEND_VM_RETURN();
 }
 
@@ -12419,6 +12431,10 @@ 

[PHP-CVS] com php-src: Add way to pass generator object to opcode handlers: Zend/zend_generators.c

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:1a99d1c8874936f7e232840a580d7bc588d63a6c
Author:Nikita Popov ni...@php.net Sat, 26 May 2012 19:40:29 +0200
Parents:   f627be52540738e124da7cb1566d7f60a2b6a48b
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=1a99d1c8874936f7e232840a580d7bc588d63a6c

Log:
Add way to pass generator object to opcode handlers

The generator zval is put into the return_value_ptr_ptr.

Changed paths:
  M  Zend/zend_generators.c


Diff:
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index de1271f..1ea910b 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -86,17 +86,23 @@ static zend_function *zend_generator_get_constructor(zval 
*object TSRMLS_DC) /*
 }
 /* }}} */
 
-static void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{ 
*/
+static void zend_generator_resume(zval *object, zend_generator *generator 
TSRMLS_DC) /* {{{ */
 {
+   /* Go to next opcode (we don't want to run the last one again) */
generator-execute_data-opline++;
+
+   /* We (mis) use the return_value_ptr_ptr to provide the generator object
+* to the executor. This way YIELD will be able to set the yielded 
value */
+   EG(return_value_ptr_ptr) = object;
+
execute_ex(generator-execute_data TSRMLS_CC);
 }
 /* }}} */
 
-static void zend_generator_ensure_initialized(zend_generator *generator 
TSRMLS_DC) /* {{{ */
+static void zend_generator_ensure_initialized(zval *object, zend_generator 
*generator TSRMLS_DC) /* {{{ */
 {
if (!generator-value) {
-   zend_generator_resume(generator TSRMLS_CC);
+   zend_generator_resume(object, generator TSRMLS_CC);
}
 }
 /* }}} */
@@ -105,15 +111,17 @@ static void 
zend_generator_ensure_initialized(zend_generator *generator TSRMLS_D
  * Rewind the generator */
 ZEND_METHOD(Generator, rewind)
 {
+   zval *object;
zend_generator *generator;
 
if (zend_parse_parameters_none() == FAILURE) {
return;
}
 
-   generator = (zend_generator *) zend_object_store_get_object(getThis() 
TSRMLS_CC);
+   object = getThis();
+   generator = (zend_generator *) zend_object_store_get_object(object 
TSRMLS_CC);
 
-   zend_generator_ensure_initialized(generator TSRMLS_CC);
+   zend_generator_ensure_initialized(object, generator TSRMLS_CC);
 }
 /* }}} */
 
@@ -121,15 +129,17 @@ ZEND_METHOD(Generator, rewind)
  * Check whether the generator is valid */
 ZEND_METHOD(Generator, valid)
 {
+   zval *object;
zend_generator *generator;
 
if (zend_parse_parameters_none() == FAILURE) {
return;
}
 
-   generator = (zend_generator *) zend_object_store_get_object(getThis() 
TSRMLS_CC);
+   object = getThis();
+   generator = (zend_generator *) zend_object_store_get_object(object 
TSRMLS_CC);
 
-   zend_generator_ensure_initialized(generator TSRMLS_CC);
+   zend_generator_ensure_initialized(object, generator TSRMLS_CC);
 }
 /* }}} */
 
@@ -137,15 +147,17 @@ ZEND_METHOD(Generator, valid)
  * Get the current value */
 ZEND_METHOD(Generator, current)
 {
+   zval *object;
zend_generator *generator;
 
if (zend_parse_parameters_none() == FAILURE) {
return;
}
 
-   generator = (zend_generator *) zend_object_store_get_object(getThis() 
TSRMLS_CC);
+   object = getThis();
+   generator = (zend_generator *) zend_object_store_get_object(object 
TSRMLS_CC);
 
-   zend_generator_ensure_initialized(generator TSRMLS_CC);
+   zend_generator_ensure_initialized(object, generator TSRMLS_CC);
 }
 /* }}} */
 
@@ -153,15 +165,17 @@ ZEND_METHOD(Generator, current)
  * Get the current key */
 ZEND_METHOD(Generator, key)
 {
+   zval *object;
zend_generator *generator;
 
if (zend_parse_parameters_none() == FAILURE) {
return;
}
 
-   generator = (zend_generator *) zend_object_store_get_object(getThis() 
TSRMLS_CC);
+   object = getThis();
+   generator = (zend_generator *) zend_object_store_get_object(object 
TSRMLS_CC);
 
-   zend_generator_ensure_initialized(generator TSRMLS_CC);
+   zend_generator_ensure_initialized(object, generator TSRMLS_CC);
 }
 /* }}} */
 
@@ -169,15 +183,16 @@ ZEND_METHOD(Generator, key)
  * Advances the generator */
 ZEND_METHOD(Generator, next)
 {
+   zval *object;
zend_generator *generator;
 
if (zend_parse_parameters_none() == FAILURE) {
return;
}
 
-   generator = (zend_generator *) zend_object_store_get_object(getThis() 
TSRMLS_CC);
+   generator = (zend_generator *) zend_object_store_get_object(object 
TSRMLS_CC);
 
-   zend_generator_ensure_initialized(generator TSRMLS_CC);
+   zend_generator_ensure_initialized(object, generator TSRMLS_CC);
 }
 /* }}} */


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Add YIELD opcode implementation: Zend/zend_compile.c Zend/zend_generators.c Zend/zend_vm_def.h Zend/zend_vm_execute.h Zend/zend_vm_opcodes.h

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:fafce58683e74a397023cc1077aae210109b40b6
Author:Nikita Popov ni...@php.net Sat, 26 May 2012 22:44:53 +0200
Parents:   1a99d1c8874936f7e232840a580d7bc588d63a6c
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=fafce58683e74a397023cc1077aae210109b40b6

Log:
Add YIELD opcode implementation

Changed paths:
  M  Zend/zend_compile.c
  M  Zend/zend_generators.c
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h
  M  Zend/zend_vm_opcodes.h

diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index f0802ef..b0e6ee2 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2660,11 +2660,17 @@ void zend_do_return(znode *expr, int do_end_vparse 
TSRMLS_DC) /* {{{ */
 
 void zend_do_yield(znode *expr TSRMLS_DC) /* {{{ */
 {
+   zend_op *opline;
+
if ((CG(active_op_array)-fn_flags  ZEND_ACC_GENERATOR) == 0) {
zend_error(E_COMPILE_ERROR, The \yield\ statement can only 
be used inside a generator function);
}
 
-   /* do nothing for now */
+   opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+
+   opline-opcode = ZEND_YIELD;
+   SET_NODE(opline-op1, expr);
+   SET_UNUSED(opline-op2);
 }
 /* }}} */
 
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 1ea910b..8161fc7 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -53,6 +53,10 @@ static void zend_generator_free_storage(zend_generator 
*generator TSRMLS_DC) /*
efree(execute_data);
}
 
+   if (generator-value) {
+   zval_ptr_dtor(generator-value);
+   }
+
efree(generator);
 }
 /* }}} */
@@ -88,14 +92,28 @@ static zend_function *zend_generator_get_constructor(zval 
*object TSRMLS_DC) /*
 
 static void zend_generator_resume(zval *object, zend_generator *generator 
TSRMLS_DC) /* {{{ */
 {
-   /* Go to next opcode (we don't want to run the last one again) */
-   generator-execute_data-opline++;
+   /* Backup executor globals */
+   zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
+   zend_op **original_opline_ptr = EG(opline_ptr);
+   zend_op_array *original_active_op_array = EG(active_op_array);
 
/* We (mis) use the return_value_ptr_ptr to provide the generator object
 * to the executor. This way YIELD will be able to set the yielded 
value */
EG(return_value_ptr_ptr) = object;
 
+   EG(opline_ptr) = generator-execute_data-opline;
+   EG(active_op_array) = generator-execute_data-op_array;
+
+   /* Go to next opcode (we don't want to run the last one again) */
+   generator-execute_data-opline++;
+
+   /* Resume execution */
execute_ex(generator-execute_data TSRMLS_CC);
+
+   /* Restore executor globals */
+   EG(return_value_ptr_ptr) = original_return_value_ptr_ptr;
+   EG(opline_ptr) = original_opline_ptr;
+   EG(active_op_array) = original_active_op_array;
 }
 /* }}} */
 
@@ -190,6 +208,7 @@ ZEND_METHOD(Generator, next)
return;
}
 
+   object = getThis();
generator = (zend_generator *) zend_object_store_get_object(object 
TSRMLS_CC);
 
zend_generator_ensure_initialized(object, generator TSRMLS_CC);
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index f4d16be..b2fc051 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -5255,4 +5255,45 @@ ZEND_VM_HANDLER(159, ZEND_SUSPEND_AND_RETURN_GENERATOR, 
ANY, ANY)
ZEND_VM_LEAVE();
 }
 
+ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV, ANY)
+{
+   /* The generator object is stored in return_value_ptr_ptr */
+   zend_generator *generator = (zend_generator *) 
zend_object_store_get_object(*EG(return_value_ptr_ptr) TSRMLS_CC);
+
+   /* Destroy the previously yielded value */
+   if (generator-value) {
+   zval_ptr_dtor(generator-value);
+   }
+
+   {
+   USE_OPLINE
+   zend_free_op free_op1;
+   zval *value = GET_OP1_ZVAL_PTR(BP_VAR_R);
+
+   /* Consts, temporary variables and references need copying */
+   if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR
+   || (PZVAL_IS_REF(value)  Z_REFCOUNT_P(value)  0)
+   ) {
+   zval *copy;
+
+   ALLOC_ZVAL(copy);
+   INIT_PZVAL_COPY(copy, value);
+
+   /* Temporary variables don't need ctor copying */
+   if (!IS_OP1_TMP_FREE()) {
+   zval_copy_ctor(copy);
+   }
+
+   generator-value = copy;
+   } else {
+   generator-value = value;
+   Z_ADDREF_P(value);
+   }
+
+   FREE_OP1_IF_VAR();
+   }
+
+   ZEND_VM_RETURN();
+}
+
 ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper)
diff --git a/Zend/zend_vm_execute.h 

[PHP-CVS] com php-src: Add support for executing a zend_execute_data: Zend/zend_execute.h Zend/zend_generators.c Zend/zend_generators.h Zend/zend_vm_execute.h Zend/zend_vm_execute.skl Zend/zend_vm_gen

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:f627be52540738e124da7cb1566d7f60a2b6a48b
Author:Nikita Popov ni...@php.net Sat, 26 May 2012 17:53:13 +0200
Parents:   ececcbce0e37a306afc1a039f52188b6c243fecc
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=f627be52540738e124da7cb1566d7f60a2b6a48b

Log:
Add support for executing a zend_execute_data

This adds another function execute_ex(), which accepts a zend_execute_data
struct to run (contrary to execute(), which accepts a zend_op_array from
which it initialized the execute_data).

This needs a bit more cleanup.

Changed paths:
  M  Zend/zend_execute.h
  M  Zend/zend_generators.c
  M  Zend/zend_generators.h
  M  Zend/zend_vm_execute.h
  M  Zend/zend_vm_execute.skl
  M  Zend/zend_vm_gen.php

diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h
index 7d42738..75a7eaa 100644
--- a/Zend/zend_execute.h
+++ b/Zend/zend_execute.h
@@ -56,6 +56,7 @@ void init_executor(TSRMLS_D);
 void shutdown_executor(TSRMLS_D);
 void shutdown_destructors(TSRMLS_D);
 ZEND_API void execute(zend_op_array *op_array TSRMLS_DC);
+ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS_DC);
 ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int 
return_value_used TSRMLS_DC);
 ZEND_API int zend_is_true(zval *op);
 #define safe_free_zval_ptr(p) safe_free_zval_ptr_rel(p ZEND_FILE_LINE_CC 
ZEND_FILE_LINE_EMPTY_CC)
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 00af655..de1271f 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -86,13 +86,34 @@ static zend_function *zend_generator_get_constructor(zval 
*object TSRMLS_DC) /*
 }
 /* }}} */
 
+static void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{ 
*/
+{
+   generator-execute_data-opline++;
+   execute_ex(generator-execute_data TSRMLS_CC);
+}
+/* }}} */
+
+static void zend_generator_ensure_initialized(zend_generator *generator 
TSRMLS_DC) /* {{{ */
+{
+   if (!generator-value) {
+   zend_generator_resume(generator TSRMLS_CC);
+   }
+}
+/* }}} */
+
 /* {{{ proto void Generator::rewind()
  * Rewind the generator */
 ZEND_METHOD(Generator, rewind)
 {
+   zend_generator *generator;
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
+
+   generator = (zend_generator *) zend_object_store_get_object(getThis() 
TSRMLS_CC);
+
+   zend_generator_ensure_initialized(generator TSRMLS_CC);
 }
 /* }}} */
 
@@ -100,9 +121,15 @@ ZEND_METHOD(Generator, rewind)
  * Check whether the generator is valid */
 ZEND_METHOD(Generator, valid)
 {
+   zend_generator *generator;
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
+
+   generator = (zend_generator *) zend_object_store_get_object(getThis() 
TSRMLS_CC);
+
+   zend_generator_ensure_initialized(generator TSRMLS_CC);
 }
 /* }}} */
 
@@ -110,9 +137,15 @@ ZEND_METHOD(Generator, valid)
  * Get the current value */
 ZEND_METHOD(Generator, current)
 {
+   zend_generator *generator;
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
+
+   generator = (zend_generator *) zend_object_store_get_object(getThis() 
TSRMLS_CC);
+
+   zend_generator_ensure_initialized(generator TSRMLS_CC);
 }
 /* }}} */
 
@@ -120,9 +153,15 @@ ZEND_METHOD(Generator, current)
  * Get the current key */
 ZEND_METHOD(Generator, key)
 {
+   zend_generator *generator;
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
+
+   generator = (zend_generator *) zend_object_store_get_object(getThis() 
TSRMLS_CC);
+
+   zend_generator_ensure_initialized(generator TSRMLS_CC);
 }
 /* }}} */
 
@@ -130,9 +169,15 @@ ZEND_METHOD(Generator, key)
  * Advances the generator */
 ZEND_METHOD(Generator, next)
 {
+   zend_generator *generator;
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
+
+   generator = (zend_generator *) zend_object_store_get_object(getThis() 
TSRMLS_CC);
+
+   zend_generator_ensure_initialized(generator TSRMLS_CC);
 }
 /* }}} */
 
diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h
index c3b8f45..1422b71 100644
--- a/Zend/zend_generators.h
+++ b/Zend/zend_generators.h
@@ -32,6 +32,8 @@ typedef struct _zend_generator {
 
/* The suspended execution context. */
zend_execute_data *execute_data;
+   /* Current value */
+   zval *value;
 } zend_generator;
 
 END_EXTERN_C()
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 8316a0a..c83a4db 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -339,25 +339,9 @@ static opcode_handler_t 
zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* o
 #define EX_Ts() EX(Ts)
 
 
-ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
-{
-   DCL_OPLINE
-
+static zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array 
*op_array, zend_bool nested 

[PHP-CVS] com php-src: Add dummy Iterator implementation: Zend/zend_generators.c

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:2c5ecb4fea3580dfe7e89be7b236b1cacbaf80de
Author:Nikita Popov ni...@php.net Wed, 23 May 2012 16:07:15 +0200
Parents:   9ce9a7e639bbb6c1c4bb34d542d2ac4e42e9457e
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=2c5ecb4fea3580dfe7e89be7b236b1cacbaf80de

Log:
Add dummy Iterator implementation

This simply adds dummy rewind/valid/current/key/next methods to Generator.

Changed paths:
  M  Zend/zend_generators.c


Diff:
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index d9ddd75..00af655 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -20,6 +20,7 @@
 
 #include zend.h
 #include zend_API.h
+#include zend_interfaces.h
 #include zend_generators.h
 
 ZEND_API zend_class_entry *zend_ce_generator;
@@ -85,7 +86,65 @@ static zend_function *zend_generator_get_constructor(zval 
*object TSRMLS_DC) /*
 }
 /* }}} */
 
+/* {{{ proto void Generator::rewind()
+ * Rewind the generator */
+ZEND_METHOD(Generator, rewind)
+{
+   if (zend_parse_parameters_none() == FAILURE) {
+   return;
+   }
+}
+/* }}} */
+
+/* {{{ proto bool Generator::valid()
+ * Check whether the generator is valid */
+ZEND_METHOD(Generator, valid)
+{
+   if (zend_parse_parameters_none() == FAILURE) {
+   return;
+   }
+}
+/* }}} */
+
+/* {{{ proto mixed Generator::current()
+ * Get the current value */
+ZEND_METHOD(Generator, current)
+{
+   if (zend_parse_parameters_none() == FAILURE) {
+   return;
+   }
+}
+/* }}} */
+
+/* {{{ proto mixed Generator::key()
+ * Get the current key */
+ZEND_METHOD(Generator, key)
+{
+   if (zend_parse_parameters_none() == FAILURE) {
+   return;
+   }
+}
+/* }}} */
+
+/* {{{ proto void Generator::next()
+ * Advances the generator */
+ZEND_METHOD(Generator, next)
+{
+   if (zend_parse_parameters_none() == FAILURE) {
+   return;
+   }
+}
+/* }}} */
+
+ZEND_BEGIN_ARG_INFO(arginfo_generator_void, 0)
+ZEND_END_ARG_INFO()
+
 static const zend_function_entry generator_functions[] = {
+   ZEND_ME(Generator, rewind,  arginfo_generator_void, ZEND_ACC_PUBLIC)
+   ZEND_ME(Generator, valid,   arginfo_generator_void, ZEND_ACC_PUBLIC)
+   ZEND_ME(Generator, current, arginfo_generator_void, ZEND_ACC_PUBLIC)
+   ZEND_ME(Generator, key, arginfo_generator_void, ZEND_ACC_PUBLIC)
+   ZEND_ME(Generator, next,arginfo_generator_void, ZEND_ACC_PUBLIC)
ZEND_FE_END
 };
 
@@ -98,6 +157,8 @@ void zend_register_generator_ce(TSRMLS_D) /* {{{ */
zend_ce_generator-ce_flags |= ZEND_ACC_FINAL_CLASS;
zend_ce_generator-create_object = zend_generator_create;
 
+   zend_class_implements(zend_ce_generator TSRMLS_CC, 1, zend_ce_iterator);
+
memcpy(zend_generator_handlers, zend_get_std_object_handlers(), 
sizeof(zend_object_handlers));
zend_generator_handlers.get_constructor = 
zend_generator_get_constructor;
 }


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Allow calling zend_vm_gen from everywhere: Zend/zend_vm_gen.php

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:ececcbce0e37a306afc1a039f52188b6c243fecc
Author:Nikita Popov ni...@php.net Wed, 23 May 2012 20:34:17 +0200
Parents:   2c5ecb4fea3580dfe7e89be7b236b1cacbaf80de
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=ececcbce0e37a306afc1a039f52188b6c243fecc

Log:
Allow calling zend_vm_gen from everywhere

Before one could only call it with cwd=Zend.

Changed paths:
  M  Zend/zend_vm_gen.php


Diff:
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index 3163000..a6314ed 100644
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -1182,7 +1182,7 @@ function gen_vm($def, $skel) {
 
// Generate opcode #defines (zend_vm_opcodes.h)
$code_len = strlen((string)$max_opcode);
-   $f = fopen(zend_vm_opcodes.h, w+) or die(ERROR: Cannot create 
zend_vm_opcodes.h\n);
+   $f = fopen(__DIR__ . /zend_vm_opcodes.h, w+) or die(ERROR: Cannot 
create zend_vm_opcodes.h\n);
 
// Insert header
out($f, $GLOBALS['header_text']);
@@ -1196,8 +1196,8 @@ function gen_vm($def, $skel) {
echo zend_vm_opcodes.h generated successfully.\n;
 
// Generate zend_vm_execute.h
-   $f = fopen(zend_vm_execute.h, w+) or die(ERROR: Cannot create 
zend_vm_execute.h\n);
-   $executor_file = realpath(zend_vm_execute.h);
+   $f = fopen(__DIR__ . /zend_vm_execute.h, w+) or die(ERROR: Cannot 
create zend_vm_execute.h\n);
+   $executor_file = realpath(__DIR__ . /zend_vm_execute.h);
 
// Insert header
out($f, $GLOBALS['header_text']);
@@ -1440,6 +1440,6 @@ if (!defined(ZEND_VM_LINES)) {
define(ZEND_VM_LINES, 0);
 }
 
-gen_vm(zend_vm_def.h, zend_vm_execute.skl);
+gen_vm(__DIR__ . /zend_vm_def.h, __DIR__ . /zend_vm_execute.skl);
 
 ?


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Add ZEND_SUSPEND_AND_RETURN_GENERATOR opcode: Zend/zend_compile.c Zend/zend_vm_def.h Zend/zend_vm_execute.h Zend/zend_vm_opcodes.h

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:1cec3f12cc719ccde286a3a55f6da1a5bf9ea2e4
Author:Nikita Popov ni...@php.net Sat, 19 May 2012 23:11:18 +0200
Parents:   e14cfafcbfbe58e0fc3f7b814698a908b0dffca5
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=1cec3f12cc719ccde286a3a55f6da1a5bf9ea2e4

Log:
Add ZEND_SUSPEND_AND_RETURN_GENERATOR opcode

If the function is a generator this opcode will be invoked right after
receiving the function arguments.

The current implementation is just a dummy.

Changed paths:
  M  Zend/zend_compile.c
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h
  M  Zend/zend_vm_opcodes.h


Diff:
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 831f9f9..f0802ef 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2670,12 +2670,18 @@ void zend_do_yield(znode *expr TSRMLS_DC) /* {{{ */
 
 void zend_do_suspend_if_generator(TSRMLS_D) /* {{{ */
 {
+   zend_op *opline;
+
// we only suspend execution if the current function is a generator
if ((CG(active_op_array)-fn_flags  ZEND_ACC_GENERATOR) == 0) {
return;
}
 
-   /* do nothing for now */
+   opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+
+   opline-opcode = ZEND_SUSPEND_AND_RETURN_GENERATOR;
+   SET_UNUSED(opline-op1);
+   SET_UNUSED(opline-op2);
 }
 /* }}} */
 
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 7b13b44..9dc7e08 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -5195,4 +5195,11 @@ ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED)
ZEND_VM_NEXT_OPCODE();
 }
 
+ZEND_VM_HANDLER(159, ZEND_SUSPEND_AND_RETURN_GENERATOR, ANY, ANY)
+{
+   /* do nothing for now */
+
+   ZEND_VM_NEXT_OPCODE();
+}
+
 ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper)
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 2096c44..c6c3af6 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -1152,6 +1152,13 @@ static int ZEND_FASTCALL  
ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS
}
 }
 
+static int ZEND_FASTCALL  
ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+   /* do nothing for now */
+
+   ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_FASTCALL  
ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
USE_OPLINE
@@ -40782,6 +40789,31 @@ void zend_init_opcodes_handlers(void)
ZEND_JMP_SET_VAR_SPEC_CV_HANDLER,
ZEND_JMP_SET_VAR_SPEC_CV_HANDLER,
ZEND_JMP_SET_VAR_SPEC_CV_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
+   ZEND_SUSPEND_AND_RETURN_GENERATOR_SPEC_HANDLER,
ZEND_NULL_HANDLER
   };
   zend_opcode_handlers = (opcode_handler_t*)labels;
diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h
index 680778c..9e24dee 100644
--- a/Zend/zend_vm_opcodes.h
+++ b/Zend/zend_vm_opcodes.h
@@ -159,3 +159,4 @@
 #define ZEND_SEPARATE156
 #define ZEND_QM_ASSIGN_VAR   157
 #define ZEND_JMP_SET_VAR 158
+#define ZEND_SUSPEND_AND_RETURN_GENERATOR159


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Add some boilerplate code for Generator class: Zend/tests/generators/errors/generator_extend_error.phpt Zend/tests/generators/errors/generator_instantiate_error.phpt Zend/tests/

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:40b7533576b4f2ec4ba872d027179d92db71d844
Author:Nikita Popov ni...@php.net Sun, 20 May 2012 14:19:16 +0200
Parents:   ca59e5464de78dae1f7c874a6bcc4f7ea2948b1d
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=40b7533576b4f2ec4ba872d027179d92db71d844

Log:
Add some boilerplate code for Generator class

The Generator class now uses a zend_generator struct, so it'll be able to
store additional info.

This commit also ensures that Generator cannot be directly instantiated
and extended. The error tests are now in a separate folder from the
(yet-to-come) functional tests.

Changed paths:
  A  Zend/tests/generators/errors/generator_extend_error.phpt
  A  Zend/tests/generators/errors/generator_instantiate_error.phpt
  A  Zend/tests/generators/errors/yield_in_normal_function_error.phpt
  A  Zend/tests/generators/errors/yield_outside_function_error.phpt
  D  Zend/tests/generators/yield_in_normal_function_error.phpt
  D  Zend/tests/generators/yield_outside_function_error.phpt
  M  Zend/zend_generators.c


Diff:
diff --git a/Zend/tests/generators/errors/generator_extend_error.phpt 
b/Zend/tests/generators/errors/generator_extend_error.phpt
new file mode 100644
index 000..550f16a
--- /dev/null
+++ b/Zend/tests/generators/errors/generator_extend_error.phpt
@@ -0,0 +1,10 @@
+--TEST--
+The Generator class cannot be extended
+--FILE--
+?php
+
+class ExtendedGenerator extends Generator { }
+
+?
+--EXPECTF--
+Fatal error: Class ExtendedGenerator may not inherit from final class 
(Generator) in %s on line %d
diff --git a/Zend/tests/generators/errors/generator_instantiate_error.phpt 
b/Zend/tests/generators/errors/generator_instantiate_error.phpt
new file mode 100644
index 000..f8941c0
--- /dev/null
+++ b/Zend/tests/generators/errors/generator_instantiate_error.phpt
@@ -0,0 +1,10 @@
+--TEST--
+It's not possible to directly instantiate the Generator class
+--FILE--
+?php
+
+new Generator;
+
+?
+--EXPECTF--
+Catchable fatal error: The Generator class is reserved for internal use and 
cannot be manually instantiated in %s on line %d
diff --git a/Zend/tests/generators/errors/yield_in_normal_function_error.phpt 
b/Zend/tests/generators/errors/yield_in_normal_function_error.phpt
new file mode 100644
index 000..802510d
--- /dev/null
+++ b/Zend/tests/generators/errors/yield_in_normal_function_error.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Yield cannot be used in normal (non-generator) functions
+--FILE--
+?php
+
+function foo() {
+yield Test;
+}
+
+?
+--EXPECTF--
+Fatal error: The yield statement can only be used inside a generator 
function in %s on line %d
diff --git a/Zend/tests/generators/errors/yield_outside_function_error.phpt 
b/Zend/tests/generators/errors/yield_outside_function_error.phpt
new file mode 100644
index 000..fd7169d
--- /dev/null
+++ b/Zend/tests/generators/errors/yield_outside_function_error.phpt
@@ -0,0 +1,10 @@
+--TEST--
+Yield cannot be used outside of functions
+--FILE--
+?php
+
+yield Test;
+
+?
+--EXPECTF--
+Fatal error: The yield statement can only be used inside a generator 
function in %s on line %d
diff --git a/Zend/tests/generators/yield_in_normal_function_error.phpt 
b/Zend/tests/generators/yield_in_normal_function_error.phpt
deleted file mode 100644
index 802510d..000
--- a/Zend/tests/generators/yield_in_normal_function_error.phpt
+++ /dev/null
@@ -1,12 +0,0 @@
---TEST--
-Yield cannot be used in normal (non-generator) functions
---FILE--
-?php
-
-function foo() {
-yield Test;
-}
-
-?
---EXPECTF--
-Fatal error: The yield statement can only be used inside a generator 
function in %s on line %d
diff --git a/Zend/tests/generators/yield_outside_function_error.phpt 
b/Zend/tests/generators/yield_outside_function_error.phpt
deleted file mode 100644
index fd7169d..000
--- a/Zend/tests/generators/yield_outside_function_error.phpt
+++ /dev/null
@@ -1,10 +0,0 @@
---TEST--
-Yield cannot be used outside of functions
---FILE--
-?php
-
-yield Test;
-
-?
---EXPECTF--
-Fatal error: The yield statement can only be used inside a generator 
function in %s on line %d
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 6f98dcb..21581db 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -23,6 +23,49 @@
 #include zend_generators.h
 
 ZEND_API zend_class_entry *zend_ce_generator;
+static zend_object_handlers zend_generator_handlers;
+
+typedef struct _zend_generator {
+   zend_object std;
+   /* nothing more for now */
+} zend_generator;
+
+static void zend_generator_free_storage(zend_generator *generator TSRMLS_DC) 
/* {{{ */
+{
+   zend_object_std_dtor(generator-std TSRMLS_CC);
+
+   efree(generator);
+}
+/* }}} */
+
+static zend_object_value zend_generator_create(zend_class_entry *class_type 
TSRMLS_DC) /* {{{ */
+{
+   zend_generator *generator;
+   zend_object_value object;
+
+   generator = emalloc(sizeof(zend_generator));
+   memset(generator, 0, sizeof(zend_generator));
+
+

[PHP-CVS] com php-src: Add empty Generator class: Zend/Makefile.am Zend/Zend.dsp Zend/ZendTS.dsp Zend/zend_default_classes.c Zend/zend_generators.c Zend/zend_generators.h configure.in win32/build/conf

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:ca59e5464de78dae1f7c874a6bcc4f7ea2948b1d
Author:Nikita Popov ni...@php.net Sun, 20 May 2012 00:03:27 +0200
Parents:   1cec3f12cc719ccde286a3a55f6da1a5bf9ea2e4
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=ca59e5464de78dae1f7c874a6bcc4f7ea2948b1d

Log:
Add empty Generator class

Changed paths:
  M  Zend/Makefile.am
  M  Zend/Zend.dsp
  M  Zend/ZendTS.dsp
  M  Zend/zend_default_classes.c
  A  Zend/zend_generators.c
  A  Zend/zend_generators.h
  M  configure.in
  M  win32/build/config.w32


Diff:
diff --git a/Zend/Makefile.am b/Zend/Makefile.am
index 5ec4590..e5757fa 100644
--- a/Zend/Makefile.am
+++ b/Zend/Makefile.am
@@ -17,7 +17,8 @@ libZend_la_SOURCES=\
zend_objects_API.c zend_ts_hash.c zend_stream.c \
zend_default_classes.c \
zend_iterators.c zend_interfaces.c zend_exceptions.c \
-   zend_strtod.c zend_closures.c zend_float.c zend_string.c zend_signal.c
+   zend_strtod.c zend_closures.c zend_float.c zend_string.c zend_signal.c \
+   zend_generators.c
 
 libZend_la_LDFLAGS =
 libZend_la_LIBADD = @ZEND_EXTRA_LIBS@
diff --git a/Zend/Zend.dsp b/Zend/Zend.dsp
index ebe0197..23ebd45 100644
--- a/Zend/Zend.dsp
+++ b/Zend/Zend.dsp
@@ -159,6 +159,10 @@ SOURCE=.\zend_float.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\zend_generators.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\zend_hash.c
 # End Source File
 # Begin Source File
diff --git a/Zend/ZendTS.dsp b/Zend/ZendTS.dsp
index 3494cd4..3be2c58 100644
--- a/Zend/ZendTS.dsp
+++ b/Zend/ZendTS.dsp
@@ -185,6 +185,10 @@ SOURCE=.\zend_extensions.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\zend_generators.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\zend_hash.c
 # End Source File
 # Begin Source File
diff --git a/Zend/zend_default_classes.c b/Zend/zend_default_classes.c
index 73a7658..bcc43ea 100644
--- a/Zend/zend_default_classes.c
+++ b/Zend/zend_default_classes.c
@@ -25,6 +25,7 @@
 #include zend_interfaces.h
 #include zend_exceptions.h
 #include zend_closures.h
+#include zend_generators.h
 
 
 ZEND_API void zend_register_default_classes(TSRMLS_D)
@@ -33,6 +34,7 @@ ZEND_API void zend_register_default_classes(TSRMLS_D)
zend_register_default_exception(TSRMLS_C);
zend_register_iterator_wrapper(TSRMLS_C);
zend_register_closure_ce(TSRMLS_C);
+   zend_register_generator_ce(TSRMLS_C);
 }
 
 /*
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
new file mode 100644
index 000..6f98dcb
--- /dev/null
+++ b/Zend/zend_generators.c
@@ -0,0 +1,47 @@
+/*
+   +--+
+   | Zend Engine  |
+   +--+
+   | Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) |
+   +--+
+   | This source file is subject to version 2.00 of the Zend license, |
+   | that is bundled with this package in the file LICENSE, and is|
+   | available through the world-wide-web at the following url:   |
+   | http://www.zend.com/license/2_00.txt.|
+   | If you did not receive a copy of the Zend license and are unable to  |
+   | obtain it through the world-wide-web, please send a note to  |
+   | lice...@zend.com so we can mail you a copy immediately.  |
+   +--+
+   | Authors: Nikita Popov ni...@php.net|
+   +--+
+*/
+
+/* $Id$ */
+
+#include zend.h
+#include zend_API.h
+#include zend_generators.h
+
+ZEND_API zend_class_entry *zend_ce_generator;
+
+static const zend_function_entry generator_functions[] = {
+   ZEND_FE_END
+};
+
+void zend_register_generator_ce(TSRMLS_D) /* {{{ */
+{
+   zend_class_entry ce;
+
+   INIT_CLASS_ENTRY(ce, Generator, generator_functions);
+   zend_ce_generator = zend_register_internal_class(ce TSRMLS_CC);
+   zend_ce_generator-ce_flags |= ZEND_ACC_FINAL_CLASS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ */
diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h
new file mode 100644
index 000..6089907
--- /dev/null
+++ b/Zend/zend_generators.h
@@ -0,0 +1,40 @@
+/*
+   +--+
+   | Zend Engine  |
+   +--+
+   | Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) |
+   +--+
+   | This source file is subject to version 2.00 of the Zend license, 

[PHP-CVS] com php-src: Add error if yield is used outside a generator: Zend/tests/generators/yield_in_normal_function_error.phpt Zend/tests/generators/yield_outside_function_error.phpt Zend/zend_compi

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:fd2a109f86d18b93d29153c2ddfa605651c7df05
Author:Nikita Popov ni...@php.net Sat, 19 May 2012 18:49:27 +0200
Parents:   9b51a3b96d89dc10d4ea65ceacaad22fa3420ea7
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=fd2a109f86d18b93d29153c2ddfa605651c7df05

Log:
Add error if yield is used outside a generator

The yield statement can only be used in generator functions, which are
marked with an asterix.

Changed paths:
  A  Zend/tests/generators/yield_in_normal_function_error.phpt
  A  Zend/tests/generators/yield_outside_function_error.phpt
  M  Zend/zend_compile.c


Diff:
diff --git a/Zend/tests/generators/yield_in_normal_function_error.phpt 
b/Zend/tests/generators/yield_in_normal_function_error.phpt
new file mode 100644
index 000..802510d
--- /dev/null
+++ b/Zend/tests/generators/yield_in_normal_function_error.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Yield cannot be used in normal (non-generator) functions
+--FILE--
+?php
+
+function foo() {
+yield Test;
+}
+
+?
+--EXPECTF--
+Fatal error: The yield statement can only be used inside a generator 
function in %s on line %d
diff --git a/Zend/tests/generators/yield_outside_function_error.phpt 
b/Zend/tests/generators/yield_outside_function_error.phpt
new file mode 100644
index 000..fd7169d
--- /dev/null
+++ b/Zend/tests/generators/yield_outside_function_error.phpt
@@ -0,0 +1,10 @@
+--TEST--
+Yield cannot be used outside of functions
+--FILE--
+?php
+
+yield Test;
+
+?
+--EXPECTF--
+Fatal error: The yield statement can only be used inside a generator 
function in %s on line %d
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 0d3ea10..d2b3536 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2660,7 +2660,11 @@ void zend_do_return(znode *expr, int do_end_vparse 
TSRMLS_DC) /* {{{ */
 
 void zend_do_yield(znode *expr TSRMLS_DC) /* {{{ */
 {
-/* do nothing for now */
+   if ((CG(active_op_array)-fn_flags  ZEND_ACC_GENERATOR) == 0) {
+   zend_error(E_COMPILE_ERROR, The \yield\ statement can only 
be used inside a generator function);
+   }
+
+   /* do nothing for now */
 }
 /* }}} */


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Minor code cleanup: Zend/zend_compile.c

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:9b51a3b96d89dc10d4ea65ceacaad22fa3420ea7
Author:Nikita Popov ni...@php.net Sat, 19 May 2012 14:21:49 +0200
Parents:   252f623464e7cf5cb794903ba07d652c9cea9a14
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=9b51a3b96d89dc10d4ea65ceacaad22fa3420ea7

Log:
Minor code cleanup

The block for the foreach separator was nested unnecessary. This commit
simply removes that nesting.

Changed paths:
  M  Zend/zend_compile.c


Diff:
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 399a37c..0d3ea10 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -1725,7 +1725,7 @@ void zend_do_begin_function_declaration(znode 
*function_token, znode *function_n
}
 
{
-   /* Push a seperator to the switch and foreach stacks */
+   /* Push a seperator to the switch stack */
zend_switch_entry switch_entry;
 
switch_entry.cond.op_type = IS_UNUSED;
@@ -1733,16 +1733,16 @@ void zend_do_begin_function_declaration(znode 
*function_token, znode *function_n
switch_entry.control_var = 0;
 
zend_stack_push(CG(switch_cond_stack), (void *) switch_entry, 
sizeof(switch_entry));
+   }
 
-   {
-   /* Foreach stack separator */
-   zend_op dummy_opline;
+   {
+   /* Push a separator to the foreach stack */
+   zend_op dummy_opline;
 
-   dummy_opline.result_type = IS_UNUSED;
-   dummy_opline.op1_type = IS_UNUSED;
+   dummy_opline.result_type = IS_UNUSED;
+   dummy_opline.op1_type = IS_UNUSED;
 
-   zend_stack_push(CG(foreach_copy_stack), (void *) 
dummy_opline, sizeof(zend_op));
-   }
+   zend_stack_push(CG(foreach_copy_stack), (void *) 
dummy_opline, sizeof(zend_op));
}
 
if (CG(doc_comment)) {


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Add T_YIELD yield keyword: Zend/zend_compile.c Zend/zend_language_parser.y Zend/zend_language_scanner.c Zend/zend_language_scanner.l Zend/zend_language_scanner_defs.h ext/stan

2012-09-01 Thread Gustavo André dos Santos Lopes
Commit:9b101ac8b364610c20f710b8c6c631db5e6230a5
Author:Nikita Popov ni...@php.net Tue, 15 May 2012 18:30:48 +0200
Parents:   d0d7340d50f178691c8e436391168cf6cc1fea3e
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=9b101ac8b364610c20f710b8c6c631db5e6230a5

Log:
Add T_YIELD yield keyword

Changed paths:
  M  Zend/zend_compile.c
  M  Zend/zend_language_parser.y
  M  Zend/zend_language_scanner.c
  M  Zend/zend_language_scanner.l
  M  Zend/zend_language_scanner_defs.h
  M  ext/standard/url_scanner_ex.c


Diff: Diff exceeded maximum size

--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Drop obsolete test: tests/lang/foreachLoop.007.phpt

2012-09-01 Thread Nikita Popov
Commit:1b5b839312b2ec1f6d38f826a592edf83188fc1e
Author:Nikita Popov ni...@php.net Sat, 1 Sep 2012 20:10:12 +0200
Parents:   53351d087dfa94569a7a65b9f4167e8f0765e05a
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=1b5b839312b2ec1f6d38f826a592edf83188fc1e

Log:
Drop obsolete test

Changed paths:
  D  tests/lang/foreachLoop.007.phpt


Diff:
diff --git a/tests/lang/foreachLoop.007.phpt b/tests/lang/foreachLoop.007.phpt
deleted file mode 100644
index 269286d..000
--- a/tests/lang/foreachLoop.007.phpt
+++ /dev/null
@@ -1,11 +0,0 @@
---TEST--
-Foreach loop tests - error case: reference to constant array.
---FILE--
-?php
-echo \nReference to constant array\n;
-foreach (array(1,2) as $v) {
-  var_dump($v);
-}
-?
---EXPECTF--
-Fatal error: Cannot create references to elements of a temporary array 
expression in %sforeachLoop.007.php on line %d


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Fix leak when yielding array as key: Zend/tests/generators/yield_array_key.phpt Zend/zend_vm_def.h Zend/zend_vm_execute.h

2012-09-01 Thread Nikita Popov
Commit:ddeb3df0b05e79213e52667f3061dc9d635e
Author:Nikita Popov ni...@php.net Sat, 1 Sep 2012 20:31:40 +0200
Parents:   1b5b839312b2ec1f6d38f826a592edf83188fc1e
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=ddeb3df0b05e79213e52667f3061dc9d635e

Log:
Fix leak when yielding array as key

The code was copy-pasted and I forgot to change OP1 to OP2 in that one
place.

Changed paths:
  A  Zend/tests/generators/yield_array_key.phpt
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h


Diff:
diff --git a/Zend/tests/generators/yield_array_key.phpt 
b/Zend/tests/generators/yield_array_key.phpt
new file mode 100644
index 000..5afba00
--- /dev/null
+++ b/Zend/tests/generators/yield_array_key.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Array keys can be yielded from generators
+--FILE--
+?php
+
+function gen() {
+yield [] = 1;
+}
+
+$gen = gen();
+var_dump($gen-key());
+var_dump($gen-current());
+
+?
+--EXPECT--
+array(0) {
+}
+int(1)
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index ffd81b0..f683ff2 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -5511,7 +5511,7 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, 
CONST|TMP|VAR|CV|UNUSE
INIT_PZVAL_COPY(copy, key);
 
/* Temporary variables don't need ctor copying */
-   if (!IS_OP1_TMP_FREE()) {
+   if (!IS_OP2_TMP_FREE()) {
zval_copy_ctor(copy);
}
 
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index b0e05b1..f8a8905 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -5005,7 +5005,7 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_
INIT_PZVAL_COPY(copy, key);
 
/* Temporary variables don't need ctor copying */
-   if (!0) {
+   if (!1) {
zval_copy_ctor(copy);
}
 
@@ -9553,7 +9553,7 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_
INIT_PZVAL_COPY(copy, key);
 
/* Temporary variables don't need ctor copying */
-   if (!1) {
+   if (!0) {
zval_copy_ctor(copy);
}
 
@@ -11266,7 +11266,7 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
INIT_PZVAL_COPY(copy, key);
 
/* Temporary variables don't need ctor copying */
-   if (!1) {
+   if (!0) {
zval_copy_ctor(copy);
}
 
@@ -11846,7 +11846,7 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
INIT_PZVAL_COPY(copy, key);
 
/* Temporary variables don't need ctor copying */
-   if (!1) {
+   if (!0) {
zval_copy_ctor(copy);
}
 
@@ -12537,7 +12537,7 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
INIT_PZVAL_COPY(copy, key);
 
/* Temporary variables don't need ctor copying */
-   if (!1) {
+   if (!0) {
zval_copy_ctor(copy);
}
 
@@ -18543,7 +18543,7 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
INIT_PZVAL_COPY(copy, key);
 
/* Temporary variables don't need ctor copying */
-   if (!0) {
+   if (!1) {
zval_copy_ctor(copy);
}
 
@@ -27081,7 +27081,7 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER
INIT_PZVAL_COPY(copy, key);
 
/* Temporary variables don't need ctor copying */
-   if (!0) {
+   if (!1) {
zval_copy_ctor(copy);
}
 
@@ -35600,7 +35600,7 @@ static int ZEND_FASTCALL  
ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
INIT_PZVAL_COPY(copy, key);
 
/* Temporary variables don't need ctor copying */
-   if (!0) {
+   if (!1) {
zval_copy_ctor(copy);
}


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: fix NEWS: NEWS

2012-09-01 Thread Stanislav Malyshev
Commit:f7d51df5c65e47a5ef8a6d81f2e13044dd926492
Author:Stanislav Malyshev s...@php.net Sat, 1 Sep 2012 16:55:51 
-0700
Parents:   f3108b5f818b2757d2e518f37d3927e83858ae4f
Branches:  PHP-5.4 master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=f7d51df5c65e47a5ef8a6d81f2e13044dd926492

Log:
fix NEWS

Changed paths:
  M  NEWS


Diff:
diff --git a/NEWS b/NEWS
index 62e2038..60bb235 100644
--- a/NEWS
+++ b/NEWS
@@ -2,11 +2,21 @@ PHP   
 NEWS
 |||
 ?? ??? 2012, PHP 5.4.8
 
-?? ??? 2012, PHP 5.4.7
-
 - Core:
+  . Added optional second argument for assert() to specify custom message. 
Patch
+by Lonny Kapelushnik (lo...@lonnylot.com). (Lars)
   . Fixed bug #62976 (Notice: could not be converted to int when comparing
 some builtin classes). (Laruence)
+  . Fixed bug #62955 (Only one directive is loaded from Per Directory Values 
+Windows registry). (aserbulov at parallels dot com)
+
+- SPL:
+  . Bug #62987 (Assigning to ArrayObject[null][something] overrides all 
+undefined variables). (Laruence)
+
+?? ??? 2012, PHP 5.4.7
+
+- Core:
   . Fixed bug (segfault while build with zts and GOTO vm-kind). (Laruence)
   . Fixed bug #62844 (parse_url() does not recognize //). (Andrew Faulds).
   . Fixed bug #62829 (stdint.h included on platform where HAVE_STDINT_H is not 
@@ -25,8 +35,6 @@ PHP   
 NEWS
 handler). (Lonny Kapelushnik)
   . Fixed bug #40459 (Stat and Dir stream wrapper methods do not call 
 constructor). (Stas)
-  . Added optional second argument for assert() to specify custom message. 
Patch
-by Lonny Kapelushnik (lo...@lonnylot.com). (Lars)
 
 - CURL:
   . Fixed bug #62912 (CURLINFO_PRIMARY_* AND CURLINFO_LOCAL_* not exposed).
@@ -64,8 +72,6 @@ PHP   
 NEWS
 when close handler call exit). (Laruence)
 
 - SPL:
-  . Bug #62987 (Assigning to ArrayObject[null][something] overrides all 
-undefined variables). (Laruence)
   . Fixed bug #62904 (Crash when cloning an object which inherits 
SplFixedArray)
 (Laruence)
   . Implemented FR #62840 (Add sort flag to ArrayObject::ksort). (Laruence)


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP-CVS] com php-src: Fix test failed due to new Token T_YIELD: ext/tokenizer/tests/bug60097.phpt

2012-09-01 Thread Xinchen Hui
Commit:4e84f725544153d5b6fff99adc274d11f79b9079
Author:Xinchen Hui larue...@php.net Sun, 2 Sep 2012 13:15:23 +0800
Parents:   664e763c2c59230dab99573d9291a9f45daecade
Branches:  master

Link:   
http://git.php.net/?p=php-src.git;a=commitdiff;h=4e84f725544153d5b6fff99adc274d11f79b9079

Log:
Fix test failed due to new Token T_YIELD

Changed paths:
  M  ext/tokenizer/tests/bug60097.phpt


Diff:
diff --git a/ext/tokenizer/tests/bug60097.phpt 
b/ext/tokenizer/tests/bug60097.phpt
index e9f1bd6..2116866 100644
--- a/ext/tokenizer/tests/bug60097.phpt
+++ b/ext/tokenizer/tests/bug60097.phpt
@@ -17,7 +17,7 @@ array(14) {
   [0]=
   array(3) {
 [0]=
-int(373)
+int(374)
 [1]=
 string(6) ?php
 
@@ -27,7 +27,7 @@ array(14) {
   [1]=
   array(3) {
 [0]=
-int(377)
+int(378)
 [1]=
 string(8) DOC1
 
@@ -37,7 +37,7 @@ array(14) {
   [2]=
   array(3) {
 [0]=
-int(380)
+int(381)
 [1]=
 string(1) {
 [2]=
@@ -46,7 +46,7 @@ array(14) {
   [3]=
   array(3) {
 [0]=
-int(309)
+int(310)
 [1]=
 string(2) $s
 [2]=
@@ -57,7 +57,7 @@ array(14) {
   [5]=
   array(3) {
 [0]=
-int(377)
+int(378)
 [1]=
 string(8) DOC2
 
@@ -67,7 +67,7 @@ array(14) {
   [6]=
   array(3) {
 [0]=
-int(378)
+int(379)
 [1]=
 string(4) DOC2
 [2]=
@@ -76,7 +76,7 @@ array(14) {
   [7]=
   array(3) {
 [0]=
-int(376)
+int(377)
 [1]=
 string(1) 
 
@@ -90,7 +90,7 @@ array(14) {
   [10]=
   array(3) {
 [0]=
-int(314)
+int(315)
 [1]=
 string(1) 
 
@@ -100,7 +100,7 @@ array(14) {
   [11]=
   array(3) {
 [0]=
-int(378)
+int(379)
 [1]=
 string(4) DOC1
 [2]=
@@ -111,7 +111,7 @@ array(14) {
   [13]=
   array(3) {
 [0]=
-int(376)
+int(377)
 [1]=
 string(1) 
 


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php