2005-01-10 22:57:36 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Zend Engine |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2012-01-01 21:15:04 +08:00
| Copyright ( c ) 1998 - 2012 Zend Technologies Ltd . ( http : //www.zend.com) |
2005-01-10 22:57:36 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| 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 |
| license @ zend . com so we can mail you a copy immediately . |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Authors : Andi Gutmans < andi @ zend . com > |
2005-10-28 14:05:57 +08:00
| Zeev Suraski < zeev @ zend . com > |
| Dmitry Stogov < dmitry @ zend . com > |
2005-01-10 22:57:36 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
/* $Id$ */
2005-06-06 23:17:20 +08:00
/* If you change this file, please regenerate the zend_vm_execute.h and
* zend_vm_opcodes . h files by running :
* php zend_vm_gen . php
*/
2004-10-23 05:42:14 +08:00
ZEND_VM_HANDLER ( 1 , ZEND_ADD , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2011-05-23 16:05:44 +08:00
fast_add_function ( & EX_T ( opline - > result . var ) . tmp_var ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 2 , ZEND_SUB , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2011-05-23 16:05:44 +08:00
fast_sub_function ( & EX_T ( opline - > result . var ) . tmp_var ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 3 , ZEND_MUL , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2011-05-23 16:05:44 +08:00
fast_mul_function ( & EX_T ( opline - > result . var ) . tmp_var ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 4 , ZEND_DIV , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2011-05-23 16:05:44 +08:00
fast_div_function ( & EX_T ( opline - > result . var ) . tmp_var ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 5 , ZEND_MOD , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2011-05-23 16:05:44 +08:00
fast_mod_function ( & EX_T ( opline - > result . var ) . tmp_var ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 6 , ZEND_SL , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
shift_left_function ( & EX_T ( opline - > result . var ) . tmp_var ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 7 , ZEND_SR , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
shift_right_function ( & EX_T ( opline - > result . var ) . tmp_var ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 8 , ZEND_CONCAT , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
concat_function ( & EX_T ( opline - > result . var ) . tmp_var ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 15 , ZEND_IS_IDENTICAL , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
is_identical_function ( & EX_T ( opline - > result . var ) . tmp_var ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 16 , ZEND_IS_NOT_IDENTICAL , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 18:57:45 +08:00
zval * result = & EX_T ( opline - > result . var ) . tmp_var ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2008-05-16 22:34:31 +08:00
is_identical_function ( result ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
2008-05-16 22:34:31 +08:00
Z_LVAL_P ( result ) = ! Z_LVAL_P ( result ) ;
2004-10-23 05:42:14 +08:00
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 17 , ZEND_IS_EQUAL , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 18:57:45 +08:00
zval * result = & EX_T ( opline - > result . var ) . tmp_var ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2011-05-23 16:05:44 +08:00
ZVAL_BOOL ( result , fast_equal_function ( result ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
2011-05-23 16:05:44 +08:00
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ) ;
2004-10-23 05:42:14 +08:00
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 18 , ZEND_IS_NOT_EQUAL , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 18:57:45 +08:00
zval * result = & EX_T ( opline - > result . var ) . tmp_var ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2011-05-23 16:05:44 +08:00
ZVAL_BOOL ( result , fast_not_equal_function ( result ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
2011-05-23 16:05:44 +08:00
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ) ;
2004-10-23 05:42:14 +08:00
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 19 , ZEND_IS_SMALLER , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 18:57:45 +08:00
zval * result = & EX_T ( opline - > result . var ) . tmp_var ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2011-05-23 16:05:44 +08:00
ZVAL_BOOL ( result , fast_is_smaller_function ( result ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
2011-05-23 16:05:44 +08:00
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ) ;
2004-10-23 05:42:14 +08:00
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 20 , ZEND_IS_SMALLER_OR_EQUAL , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 18:57:45 +08:00
zval * result = & EX_T ( opline - > result . var ) . tmp_var ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2011-05-23 16:05:44 +08:00
ZVAL_BOOL ( result , fast_is_smaller_or_equal_function ( result ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
2011-05-23 16:05:44 +08:00
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ) ;
2004-10-23 05:42:14 +08:00
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 9 , ZEND_BW_OR , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
bitwise_or_function ( & EX_T ( opline - > result . var ) . tmp_var ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 10 , ZEND_BW_AND , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
bitwise_and_function ( & EX_T ( opline - > result . var ) . tmp_var ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 11 , ZEND_BW_XOR , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
bitwise_xor_function ( & EX_T ( opline - > result . var ) . tmp_var ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 14 , ZEND_BOOL_XOR , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
boolean_xor_function ( & EX_T ( opline - > result . var ) . tmp_var ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 12 , ZEND_BW_NOT , CONST | TMP | VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
bitwise_not_function ( & EX_T ( opline - > result . var ) . tmp_var ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP1 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 13 , ZEND_BOOL_NOT , CONST | TMP | VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
boolean_not_function ( & EX_T ( opline - > result . var ) . tmp_var ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP1 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2005-04-27 20:16:32 +08:00
ZEND_VM_HELPER_EX ( zend_binary_assign_op_obj_helper , VAR | UNUSED | CV , CONST | TMP | VAR | UNUSED | CV , int ( * binary_op ) ( zval * result , zval * op1 , zval * op2 TSRMLS_DC ) )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 , free_op_data1 ;
2010-07-19 23:04:51 +08:00
zval * * object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
2004-10-23 05:42:14 +08:00
zval * object ;
zval * property = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2012-12-04 14:14:39 +08:00
zval * value = get_zval_ptr ( ( opline + 1 ) - > op1_type , & ( opline + 1 ) - > op1 , execute_data , & free_op_data1 , BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
int have_get_ptr = 0 ;
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( object_ptr = = NULL ) ) {
2009-03-18 20:53:17 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an object " ) ;
}
2004-10-23 05:42:14 +08:00
make_real_object ( object_ptr TSRMLS_CC ) ;
object = * object_ptr ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( object ) ! = IS_OBJECT ) ) {
2004-10-23 05:42:14 +08:00
zend_error ( E_WARNING , " Attempt to assign property of non-object " ) ;
FREE_OP2 ( ) ;
FREE_OP ( free_op_data1 ) ;
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2010-04-20 19:16:39 +08:00
PZVAL_LOCK ( & EG ( uninitialized_zval ) ) ;
EX_T ( opline - > result . var ) . var . ptr = & EG ( uninitialized_zval ) ;
EX_T ( opline - > result . var ) . var . ptr_ptr = NULL ;
2004-10-23 05:42:14 +08:00
}
} else {
/* here we are sure we are dealing with an object */
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
MAKE_REAL_ZVAL_PTR ( property ) ;
2004-10-23 05:42:14 +08:00
}
/* here property is a string */
if ( opline - > extended_value = = ZEND_ASSIGN_OBJ
& & Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ) {
2010-04-20 18:57:45 +08:00
zval * * zptr = Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ( object , property , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
if ( zptr ! = NULL ) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF ( zptr ) ;
have_get_ptr = 1 ;
binary_op ( * zptr , * zptr , value TSRMLS_CC ) ;
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2007-12-14 22:14:50 +08:00
PZVAL_LOCK ( * zptr ) ;
2010-04-20 19:16:39 +08:00
EX_T ( opline - > result . var ) . var . ptr = * zptr ;
EX_T ( opline - > result . var ) . var . ptr_ptr = NULL ;
2004-10-23 05:42:14 +08:00
}
}
}
if ( ! have_get_ptr ) {
2005-04-16 01:15:18 +08:00
zval * z = NULL ;
2004-10-23 05:42:14 +08:00
2009-03-18 20:53:17 +08:00
if ( opline - > extended_value = = ZEND_ASSIGN_OBJ ) {
if ( Z_OBJ_HT_P ( object ) - > read_property ) {
2010-04-20 18:57:45 +08:00
z = Z_OBJ_HT_P ( object ) - > read_property ( object , property , BP_VAR_R , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) TSRMLS_CC ) ;
2009-03-18 20:53:17 +08:00
}
} else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
if ( Z_OBJ_HT_P ( object ) - > read_dimension ) {
z = Z_OBJ_HT_P ( object ) - > read_dimension ( object , property , BP_VAR_R TSRMLS_CC ) ;
}
2004-10-23 05:42:14 +08:00
}
2005-04-16 01:15:18 +08:00
if ( z ) {
2006-05-12 05:07:39 +08:00
if ( Z_TYPE_P ( z ) = = IS_OBJECT & & Z_OBJ_HT_P ( z ) - > get ) {
2005-04-16 01:15:18 +08:00
zval * value = Z_OBJ_HT_P ( z ) - > get ( z TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2007-10-07 13:22:07 +08:00
if ( Z_REFCOUNT_P ( z ) = = 0 ) {
2008-01-22 17:27:48 +08:00
GC_REMOVE_ZVAL_FROM_BUFFER ( z ) ;
2005-04-16 01:15:18 +08:00
zval_dtor ( z ) ;
FREE_ZVAL ( z ) ;
}
z = value ;
}
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( z ) ;
2005-04-16 01:15:18 +08:00
SEPARATE_ZVAL_IF_NOT_REF ( & z ) ;
binary_op ( z , z , value TSRMLS_CC ) ;
2009-03-18 20:53:17 +08:00
if ( opline - > extended_value = = ZEND_ASSIGN_OBJ ) {
2010-04-20 18:57:45 +08:00
Z_OBJ_HT_P ( object ) - > write_property ( object , property , z , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) TSRMLS_CC ) ;
2009-03-18 20:53:17 +08:00
} else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
Z_OBJ_HT_P ( object ) - > write_dimension ( object , property , z TSRMLS_CC ) ;
2005-04-16 01:15:18 +08:00
}
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2007-12-14 22:14:50 +08:00
PZVAL_LOCK ( z ) ;
2010-04-20 19:16:39 +08:00
EX_T ( opline - > result . var ) . var . ptr = z ;
EX_T ( opline - > result . var ) . var . ptr_ptr = NULL ;
2005-04-16 01:15:18 +08:00
}
zval_ptr_dtor ( & z ) ;
} else {
zend_error ( E_WARNING , " Attempt to assign property of non-object " ) ;
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2010-04-20 19:16:39 +08:00
PZVAL_LOCK ( & EG ( uninitialized_zval ) ) ;
EX_T ( opline - > result . var ) . var . ptr = & EG ( uninitialized_zval ) ;
EX_T ( opline - > result . var ) . var . ptr_ptr = NULL ;
2004-10-23 05:42:14 +08:00
}
}
}
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
zval_ptr_dtor ( & property ) ;
} else {
FREE_OP2 ( ) ;
2004-10-23 05:42:14 +08:00
}
FREE_OP ( free_op_data1 ) ;
}
FREE_OP1_VAR_PTR ( ) ;
/* assign_obj has two opcodes! */
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_INC_OPCODE ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2005-04-27 20:16:32 +08:00
ZEND_VM_HELPER_EX ( zend_binary_assign_op_helper , VAR | UNUSED | CV , CONST | TMP | VAR | UNUSED | CV , int ( * binary_op ) ( zval * result , zval * op1 , zval * op2 TSRMLS_DC ) )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 , free_op_data2 , free_op_data1 ;
zval * * var_ptr ;
zval * value ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
switch ( opline - > extended_value ) {
case ZEND_ASSIGN_OBJ :
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_obj_helper , binary_op , binary_op ) ;
break ;
case ZEND_ASSIGN_DIM : {
2009-03-18 20:53:17 +08:00
zval * * container = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2009-03-18 20:53:17 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an array " ) ;
2010-04-20 19:16:39 +08:00
} else if ( UNEXPECTED ( Z_TYPE_PP ( container ) = = IS_OBJECT ) ) {
2009-03-18 20:53:17 +08:00
if ( OP1_TYPE = = IS_VAR & & ! OP1_FREE ) {
Z_ADDREF_PP ( container ) ; /* undo the effect of get_obj_zval_ptr_ptr() */
}
2004-10-23 05:42:14 +08:00
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_obj_helper , binary_op , binary_op ) ;
} else {
2005-06-03 19:16:19 +08:00
zval * dim = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
zend_fetch_dimension_address ( & EX_T ( ( opline + 1 ) - > op2 . var ) , container , dim , OP2_TYPE , BP_VAR_RW TSRMLS_CC ) ;
2012-12-04 14:14:39 +08:00
value = get_zval_ptr ( ( opline + 1 ) - > op1_type , & ( opline + 1 ) - > op1 , execute_data , & free_op_data1 , BP_VAR_R ) ;
var_ptr = _get_zval_ptr_ptr_var ( ( opline + 1 ) - > op2 . var , execute_data , & free_op_data2 TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
}
}
break ;
default :
value = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
var_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
/* do nothing */
break ;
}
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( var_ptr = = NULL ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use assign-op operators with overloaded objects nor string offsets " ) ;
}
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( * var_ptr = = & EG ( error_zval ) ) ) {
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2010-04-20 19:16:39 +08:00
PZVAL_LOCK ( & EG ( uninitialized_zval ) ) ;
AI_SET_PTR ( & EX_T ( opline - > result . var ) , & EG ( uninitialized_zval ) ) ;
2004-10-23 05:42:14 +08:00
}
FREE_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
if ( opline - > extended_value = = ZEND_ASSIGN_DIM ) {
ZEND_VM_INC_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
SEPARATE_ZVAL_IF_NOT_REF ( var_ptr ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( Z_TYPE_PP ( var_ptr ) = = IS_OBJECT )
& & Z_OBJ_HANDLER_PP ( var_ptr , get )
2004-10-23 05:42:14 +08:00
& & Z_OBJ_HANDLER_PP ( var_ptr , set ) ) {
/* proxy object */
zval * objval = Z_OBJ_HANDLER_PP ( var_ptr , get ) ( * var_ptr TSRMLS_CC ) ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( objval ) ;
2004-10-23 05:42:14 +08:00
binary_op ( objval , objval , value TSRMLS_CC ) ;
Z_OBJ_HANDLER_PP ( var_ptr , set ) ( var_ptr , objval TSRMLS_CC ) ;
zval_ptr_dtor ( & objval ) ;
} else {
binary_op ( * var_ptr , * var_ptr , value TSRMLS_CC ) ;
}
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2004-10-23 05:42:14 +08:00
PZVAL_LOCK ( * var_ptr ) ;
2010-04-20 19:16:39 +08:00
AI_SET_PTR ( & EX_T ( opline - > result . var ) , * var_ptr ) ;
2004-10-23 05:42:14 +08:00
}
FREE_OP2 ( ) ;
2009-03-18 20:53:17 +08:00
if ( opline - > extended_value = = ZEND_ASSIGN_DIM ) {
2005-07-03 19:09:42 +08:00
FREE_OP ( free_op_data1 ) ;
2004-10-23 05:42:14 +08:00
FREE_OP_VAR_PTR ( free_op_data2 ) ;
2010-04-20 19:16:39 +08:00
FREE_OP1_VAR_PTR ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_INC_OPCODE ( ) ;
} else {
FREE_OP1_VAR_PTR ( ) ;
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
ZEND_VM_NEXT_OPCODE ( ) ;
}
2005-04-27 20:16:32 +08:00
ZEND_VM_HANDLER ( 23 , ZEND_ASSIGN_ADD , VAR | UNUSED | CV , CONST | TMP | VAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , add_function ) ;
}
2005-04-27 20:16:32 +08:00
ZEND_VM_HANDLER ( 24 , ZEND_ASSIGN_SUB , VAR | UNUSED | CV , CONST | TMP | VAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , sub_function ) ;
}
2005-04-27 20:16:32 +08:00
ZEND_VM_HANDLER ( 25 , ZEND_ASSIGN_MUL , VAR | UNUSED | CV , CONST | TMP | VAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , mul_function ) ;
}
2005-04-27 20:16:32 +08:00
ZEND_VM_HANDLER ( 26 , ZEND_ASSIGN_DIV , VAR | UNUSED | CV , CONST | TMP | VAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , div_function ) ;
}
2005-04-27 20:16:32 +08:00
ZEND_VM_HANDLER ( 27 , ZEND_ASSIGN_MOD , VAR | UNUSED | CV , CONST | TMP | VAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , mod_function ) ;
}
2005-04-27 20:16:32 +08:00
ZEND_VM_HANDLER ( 28 , ZEND_ASSIGN_SL , VAR | UNUSED | CV , CONST | TMP | VAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , shift_left_function ) ;
}
2005-04-27 20:16:32 +08:00
ZEND_VM_HANDLER ( 29 , ZEND_ASSIGN_SR , VAR | UNUSED | CV , CONST | TMP | VAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , shift_right_function ) ;
}
2005-04-27 20:16:32 +08:00
ZEND_VM_HANDLER ( 30 , ZEND_ASSIGN_CONCAT , VAR | UNUSED | CV , CONST | TMP | VAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , concat_function ) ;
}
2005-04-27 20:16:32 +08:00
ZEND_VM_HANDLER ( 31 , ZEND_ASSIGN_BW_OR , VAR | UNUSED | CV , CONST | TMP | VAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , bitwise_or_function ) ;
}
2005-04-27 20:16:32 +08:00
ZEND_VM_HANDLER ( 32 , ZEND_ASSIGN_BW_AND , VAR | UNUSED | CV , CONST | TMP | VAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , bitwise_and_function ) ;
}
2005-04-27 20:16:32 +08:00
ZEND_VM_HANDLER ( 33 , ZEND_ASSIGN_BW_XOR , VAR | UNUSED | CV , CONST | TMP | VAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , bitwise_xor_function ) ;
}
ZEND_VM_HELPER_EX ( zend_pre_incdec_property_helper , VAR | UNUSED | CV , CONST | TMP | VAR | CV , incdec_t incdec_op )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
zval * * object_ptr ;
2004-10-23 05:42:14 +08:00
zval * object ;
2010-04-20 19:16:39 +08:00
zval * property ;
zval * * retval ;
2004-10-23 05:42:14 +08:00
int have_get_ptr = 0 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-07-19 23:04:51 +08:00
object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
2010-04-20 19:16:39 +08:00
property = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
retval = & EX_T ( opline - > result . var ) . var . ptr ;
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( object_ptr = = NULL ) ) {
2009-03-18 20:53:17 +08:00
zend_error_noreturn ( E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
}
2004-10-23 05:42:14 +08:00
make_real_object ( object_ptr TSRMLS_CC ) ; /* this should modify object only if it's empty */
object = * object_ptr ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( object ) ! = IS_OBJECT ) ) {
2004-10-23 05:42:14 +08:00
zend_error ( E_WARNING , " Attempt to increment/decrement property of non-object " ) ;
FREE_OP2 ( ) ;
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2010-04-20 19:16:39 +08:00
PZVAL_LOCK ( & EG ( uninitialized_zval ) ) ;
* retval = & EG ( uninitialized_zval ) ;
2004-10-23 05:42:14 +08:00
}
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
/* here we are sure we are dealing with an object */
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
MAKE_REAL_ZVAL_PTR ( property ) ;
}
2004-10-23 05:42:14 +08:00
if ( Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ) {
2010-04-20 18:57:45 +08:00
zval * * zptr = Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ( object , property , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
if ( zptr ! = NULL ) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF ( zptr ) ;
have_get_ptr = 1 ;
incdec_op ( * zptr ) ;
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2004-10-23 05:42:14 +08:00
* retval = * zptr ;
PZVAL_LOCK ( * retval ) ;
}
}
}
if ( ! have_get_ptr ) {
2005-04-16 01:15:18 +08:00
if ( Z_OBJ_HT_P ( object ) - > read_property & & Z_OBJ_HT_P ( object ) - > write_property ) {
2010-04-20 18:57:45 +08:00
zval * z = Z_OBJ_HT_P ( object ) - > read_property ( object , property , BP_VAR_R , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( z ) = = IS_OBJECT ) & & Z_OBJ_HT_P ( z ) - > get ) {
2005-04-16 01:15:18 +08:00
zval * value = Z_OBJ_HT_P ( z ) - > get ( z TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2007-10-07 13:22:07 +08:00
if ( Z_REFCOUNT_P ( z ) = = 0 ) {
2008-01-22 17:27:48 +08:00
GC_REMOVE_ZVAL_FROM_BUFFER ( z ) ;
2005-04-16 01:15:18 +08:00
zval_dtor ( z ) ;
FREE_ZVAL ( z ) ;
}
z = value ;
}
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( z ) ;
2005-04-16 01:15:18 +08:00
SEPARATE_ZVAL_IF_NOT_REF ( & z ) ;
incdec_op ( z ) ;
* retval = z ;
2010-04-20 18:57:45 +08:00
Z_OBJ_HT_P ( object ) - > write_property ( object , property , z , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) TSRMLS_CC ) ;
SELECTIVE_PZVAL_LOCK ( * retval , opline ) ;
2005-04-16 01:15:18 +08:00
zval_ptr_dtor ( & z ) ;
} else {
zend_error ( E_WARNING , " Attempt to increment/decrement property of non-object " ) ;
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2010-04-20 19:16:39 +08:00
PZVAL_LOCK ( & EG ( uninitialized_zval ) ) ;
* retval = & EG ( uninitialized_zval ) ;
2004-10-23 05:42:14 +08:00
}
}
}
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
zval_ptr_dtor ( & property ) ;
} else {
FREE_OP2 ( ) ;
}
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 132 , ZEND_PRE_INC_OBJ , VAR | UNUSED | CV , CONST | TMP | VAR | CV )
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_pre_incdec_property_helper , incdec_op , increment_function ) ;
}
ZEND_VM_HANDLER ( 133 , ZEND_PRE_DEC_OBJ , VAR | UNUSED | CV , CONST | TMP | VAR | CV )
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_pre_incdec_property_helper , incdec_op , decrement_function ) ;
}
ZEND_VM_HELPER_EX ( zend_post_incdec_property_helper , VAR | UNUSED | CV , CONST | TMP | VAR | CV , incdec_t incdec_op )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
zval * * object_ptr ;
2004-10-23 05:42:14 +08:00
zval * object ;
2010-04-20 19:16:39 +08:00
zval * property ;
zval * retval ;
2004-10-23 05:42:14 +08:00
int have_get_ptr = 0 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-07-19 23:04:51 +08:00
object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
2010-04-20 19:16:39 +08:00
property = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
retval = & EX_T ( opline - > result . var ) . tmp_var ;
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( object_ptr = = NULL ) ) {
2009-03-18 20:53:17 +08:00
zend_error_noreturn ( E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
}
2004-10-23 05:42:14 +08:00
make_real_object ( object_ptr TSRMLS_CC ) ; /* this should modify object only if it's empty */
object = * object_ptr ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( object ) ! = IS_OBJECT ) ) {
2004-10-23 05:42:14 +08:00
zend_error ( E_WARNING , " Attempt to increment/decrement property of non-object " ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
ZVAL_NULL ( retval ) ;
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
/* here we are sure we are dealing with an object */
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
MAKE_REAL_ZVAL_PTR ( property ) ;
}
2004-10-23 05:42:14 +08:00
if ( Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ) {
2010-04-20 18:57:45 +08:00
zval * * zptr = Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ( object , property , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
if ( zptr ! = NULL ) { /* NULL means no success in getting PTR */
have_get_ptr = 1 ;
SEPARATE_ZVAL_IF_NOT_REF ( zptr ) ;
2010-04-20 19:16:39 +08:00
ZVAL_COPY_VALUE ( retval , * zptr ) ;
2004-10-23 05:42:14 +08:00
zendi_zval_copy_ctor ( * retval ) ;
incdec_op ( * zptr ) ;
}
}
if ( ! have_get_ptr ) {
2005-04-16 01:15:18 +08:00
if ( Z_OBJ_HT_P ( object ) - > read_property & & Z_OBJ_HT_P ( object ) - > write_property ) {
2010-04-20 18:57:45 +08:00
zval * z = Z_OBJ_HT_P ( object ) - > read_property ( object , property , BP_VAR_R , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) TSRMLS_CC ) ;
2005-04-26 21:23:23 +08:00
zval * z_copy ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( z ) = = IS_OBJECT ) & & Z_OBJ_HT_P ( z ) - > get ) {
2005-04-16 01:15:18 +08:00
zval * value = Z_OBJ_HT_P ( z ) - > get ( z TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2007-10-07 13:22:07 +08:00
if ( Z_REFCOUNT_P ( z ) = = 0 ) {
2008-01-22 17:27:48 +08:00
GC_REMOVE_ZVAL_FROM_BUFFER ( z ) ;
2005-04-16 01:15:18 +08:00
zval_dtor ( z ) ;
FREE_ZVAL ( z ) ;
}
z = value ;
2004-10-23 05:42:14 +08:00
}
2010-04-20 19:16:39 +08:00
ZVAL_COPY_VALUE ( retval , z ) ;
2005-04-16 01:15:18 +08:00
zendi_zval_copy_ctor ( * retval ) ;
2005-04-26 21:23:23 +08:00
ALLOC_ZVAL ( z_copy ) ;
2010-04-20 19:16:39 +08:00
INIT_PZVAL_COPY ( z_copy , z ) ;
2005-04-26 21:23:23 +08:00
zendi_zval_copy_ctor ( * z_copy ) ;
incdec_op ( z_copy ) ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( z ) ;
2010-04-20 18:57:45 +08:00
Z_OBJ_HT_P ( object ) - > write_property ( object , property , z_copy , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) TSRMLS_CC ) ;
2005-04-26 21:23:23 +08:00
zval_ptr_dtor ( & z_copy ) ;
2005-04-16 01:15:18 +08:00
zval_ptr_dtor ( & z ) ;
} else {
zend_error ( E_WARNING , " Attempt to increment/decrement property of non-object " ) ;
2010-04-20 19:16:39 +08:00
ZVAL_NULL ( retval ) ;
2004-10-23 05:42:14 +08:00
}
}
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
zval_ptr_dtor ( & property ) ;
} else {
FREE_OP2 ( ) ;
}
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 134 , ZEND_POST_INC_OBJ , VAR | UNUSED | CV , CONST | TMP | VAR | CV )
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_post_incdec_property_helper , incdec_op , increment_function ) ;
}
ZEND_VM_HANDLER ( 135 , ZEND_POST_DEC_OBJ , VAR | UNUSED | CV , CONST | TMP | VAR | CV )
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_post_incdec_property_helper , incdec_op , decrement_function ) ;
}
ZEND_VM_HANDLER ( 34 , ZEND_PRE_INC , VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
zval * * var_ptr ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
var_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( var_ptr = = NULL ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
}
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( * var_ptr = = & EG ( error_zval ) ) ) {
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2010-04-20 19:16:39 +08:00
PZVAL_LOCK ( & EG ( uninitialized_zval ) ) ;
AI_SET_PTR ( & EX_T ( opline - > result . var ) , & EG ( uninitialized_zval ) ) ;
2004-10-23 05:42:14 +08:00
}
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
SEPARATE_ZVAL_IF_NOT_REF ( var_ptr ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( Z_TYPE_PP ( var_ptr ) = = IS_OBJECT )
& & Z_OBJ_HANDLER_PP ( var_ptr , get )
2004-10-23 05:42:14 +08:00
& & Z_OBJ_HANDLER_PP ( var_ptr , set ) ) {
/* proxy object */
zval * val = Z_OBJ_HANDLER_PP ( var_ptr , get ) ( * var_ptr TSRMLS_CC ) ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( val ) ;
2011-05-23 16:05:44 +08:00
fast_increment_function ( val ) ;
2004-10-23 05:42:14 +08:00
Z_OBJ_HANDLER_PP ( var_ptr , set ) ( var_ptr , val TSRMLS_CC ) ;
zval_ptr_dtor ( & val ) ;
} else {
2011-05-23 16:05:44 +08:00
fast_increment_function ( * var_ptr ) ;
2004-10-23 05:42:14 +08:00
}
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2004-10-23 05:42:14 +08:00
PZVAL_LOCK ( * var_ptr ) ;
2010-04-20 19:16:39 +08:00
AI_SET_PTR ( & EX_T ( opline - > result . var ) , * var_ptr ) ;
2004-10-23 05:42:14 +08:00
}
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 35 , ZEND_PRE_DEC , VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
zval * * var_ptr ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
var_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( var_ptr = = NULL ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
}
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( * var_ptr = = & EG ( error_zval ) ) ) {
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2010-04-20 19:16:39 +08:00
PZVAL_LOCK ( & EG ( uninitialized_zval ) ) ;
AI_SET_PTR ( & EX_T ( opline - > result . var ) , & EG ( uninitialized_zval ) ) ;
2004-10-23 05:42:14 +08:00
}
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
SEPARATE_ZVAL_IF_NOT_REF ( var_ptr ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( Z_TYPE_PP ( var_ptr ) = = IS_OBJECT )
& & Z_OBJ_HANDLER_PP ( var_ptr , get )
2004-10-23 05:42:14 +08:00
& & Z_OBJ_HANDLER_PP ( var_ptr , set ) ) {
/* proxy object */
zval * val = Z_OBJ_HANDLER_PP ( var_ptr , get ) ( * var_ptr TSRMLS_CC ) ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( val ) ;
2011-05-23 16:05:44 +08:00
fast_decrement_function ( val ) ;
2004-10-23 05:42:14 +08:00
Z_OBJ_HANDLER_PP ( var_ptr , set ) ( var_ptr , val TSRMLS_CC ) ;
zval_ptr_dtor ( & val ) ;
} else {
2011-05-23 16:05:44 +08:00
fast_decrement_function ( * var_ptr ) ;
2004-10-23 05:42:14 +08:00
}
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2004-10-23 05:42:14 +08:00
PZVAL_LOCK ( * var_ptr ) ;
2010-04-20 19:16:39 +08:00
AI_SET_PTR ( & EX_T ( opline - > result . var ) , * var_ptr ) ;
2004-10-23 05:42:14 +08:00
}
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 36 , ZEND_POST_INC , VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
zval * * var_ptr , * retval ;
SAVE_OPLINE ( ) ;
var_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( var_ptr = = NULL ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
}
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( * var_ptr = = & EG ( error_zval ) ) ) {
2010-07-19 22:34:34 +08:00
ZVAL_NULL ( & EX_T ( opline - > result . var ) . tmp_var ) ;
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2010-04-20 19:16:39 +08:00
retval = & EX_T ( opline - > result . var ) . tmp_var ;
ZVAL_COPY_VALUE ( retval , * var_ptr ) ;
zendi_zval_copy_ctor ( * retval ) ;
2004-10-23 05:42:14 +08:00
SEPARATE_ZVAL_IF_NOT_REF ( var_ptr ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( Z_TYPE_PP ( var_ptr ) = = IS_OBJECT )
& & Z_OBJ_HANDLER_PP ( var_ptr , get )
2004-10-23 05:42:14 +08:00
& & Z_OBJ_HANDLER_PP ( var_ptr , set ) ) {
/* proxy object */
zval * val = Z_OBJ_HANDLER_PP ( var_ptr , get ) ( * var_ptr TSRMLS_CC ) ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( val ) ;
2011-05-23 16:05:44 +08:00
fast_increment_function ( val ) ;
2004-10-23 05:42:14 +08:00
Z_OBJ_HANDLER_PP ( var_ptr , set ) ( var_ptr , val TSRMLS_CC ) ;
zval_ptr_dtor ( & val ) ;
} else {
2011-05-23 16:05:44 +08:00
fast_increment_function ( * var_ptr ) ;
2004-10-23 05:42:14 +08:00
}
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 37 , ZEND_POST_DEC , VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
zval * * var_ptr , * retval ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
var_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( var_ptr = = NULL ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
}
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( * var_ptr = = & EG ( error_zval ) ) ) {
2010-07-19 22:34:34 +08:00
ZVAL_NULL ( & EX_T ( opline - > result . var ) . tmp_var ) ;
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2010-04-20 19:16:39 +08:00
retval = & EX_T ( opline - > result . var ) . tmp_var ;
ZVAL_COPY_VALUE ( retval , * var_ptr ) ;
zendi_zval_copy_ctor ( * retval ) ;
2004-10-23 05:42:14 +08:00
SEPARATE_ZVAL_IF_NOT_REF ( var_ptr ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( Z_TYPE_PP ( var_ptr ) = = IS_OBJECT )
& & Z_OBJ_HANDLER_PP ( var_ptr , get )
2004-10-23 05:42:14 +08:00
& & Z_OBJ_HANDLER_PP ( var_ptr , set ) ) {
/* proxy object */
zval * val = Z_OBJ_HANDLER_PP ( var_ptr , get ) ( * var_ptr TSRMLS_CC ) ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( val ) ;
2011-05-23 16:05:44 +08:00
fast_decrement_function ( val ) ;
2004-10-23 05:42:14 +08:00
Z_OBJ_HANDLER_PP ( var_ptr , set ) ( var_ptr , val TSRMLS_CC ) ;
zval_ptr_dtor ( & val ) ;
} else {
2011-05-23 16:05:44 +08:00
fast_decrement_function ( * var_ptr ) ;
2004-10-23 05:42:14 +08:00
}
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 40 , ZEND_ECHO , CONST | TMP | VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
zval z_copy ;
2010-04-20 19:16:39 +08:00
zval * z ;
SAVE_OPLINE ( ) ;
z = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2009-04-08 21:19:34 +08:00
if ( OP1_TYPE ! = IS_CONST & &
2010-04-20 19:16:39 +08:00
UNEXPECTED ( Z_TYPE_P ( z ) = = IS_OBJECT ) & &
2011-07-11 18:31:49 +08:00
Z_OBJ_HT_P ( z ) - > get_method ! = NULL ) {
if ( OP1_TYPE = = IS_TMP_VAR ) {
INIT_PZVAL ( z ) ;
}
if ( zend_std_cast_object_tostring ( z , & z_copy , IS_STRING TSRMLS_CC ) = = SUCCESS ) {
zend_print_variable ( & z_copy ) ;
zval_dtor ( & z_copy ) ;
} else {
zend_print_variable ( z ) ;
}
2004-10-23 05:42:14 +08:00
} else {
zend_print_variable ( z ) ;
}
FREE_OP1 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 41 , ZEND_PRINT , CONST | TMP | VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
ZVAL_LONG ( & EX_T ( opline - > result . var ) . tmp_var , 1 ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_DISPATCH_TO_HANDLER ( ZEND_ECHO ) ;
}
2010-05-06 18:27:35 +08:00
ZEND_VM_HELPER_EX ( zend_fetch_var_address_helper , CONST | TMP | VAR | CV , UNUSED | CONST | VAR , int type )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
zval * varname ;
2004-10-23 05:42:14 +08:00
zval * * retval ;
zval tmp_varname ;
HashTable * target_symbol_table ;
2010-04-20 18:57:45 +08:00
ulong hash_value ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
varname = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
if ( OP1_TYPE ! = IS_CONST & & UNEXPECTED ( Z_TYPE_P ( varname ) ! = IS_STRING ) ) {
ZVAL_COPY_VALUE ( & tmp_varname , varname ) ;
2004-10-23 05:42:14 +08:00
zval_copy_ctor ( & tmp_varname ) ;
2011-03-16 13:25:02 +08:00
Z_SET_REFCOUNT ( tmp_varname , 1 ) ;
Z_UNSET_ISREF ( tmp_varname ) ;
2004-10-23 05:42:14 +08:00
convert_to_string ( & tmp_varname ) ;
varname = & tmp_varname ;
}
2010-05-06 18:27:35 +08:00
if ( OP2_TYPE ! = IS_UNUSED ) {
zend_class_entry * ce ;
if ( OP2_TYPE = = IS_CONST ) {
2010-05-24 22:11:39 +08:00
if ( CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ) {
ce = CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ;
} else {
ce = zend_fetch_class_by_name ( Z_STRVAL_P ( opline - > op2 . zv ) , Z_STRLEN_P ( opline - > op2 . zv ) , opline - > op2 . literal + 1 , 0 TSRMLS_CC ) ;
2012-02-25 21:56:59 +08:00
if ( UNEXPECTED ( ce = = NULL ) ) {
if ( OP1_TYPE ! = IS_CONST & & varname = = & tmp_varname ) {
zval_dtor ( & tmp_varname ) ;
}
FREE_OP1 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2010-05-24 22:11:39 +08:00
CACHE_PTR ( opline - > op2 . literal - > cache_slot , ce ) ;
}
2010-05-06 18:27:35 +08:00
} else {
ce = EX_T ( opline - > op2 . var ) . class_entry ;
}
retval = zend_std_get_static_property ( ce , Z_STRVAL_P ( varname ) , Z_STRLEN_P ( varname ) , 0 , ( ( OP1_TYPE = = IS_CONST ) ? opline - > op1 . literal : NULL ) TSRMLS_CC ) ;
2009-09-21 21:01:17 +08:00
FREE_OP1 ( ) ;
2004-10-23 05:42:14 +08:00
} else {
2010-04-20 18:57:45 +08:00
target_symbol_table = zend_get_target_symbol_table ( opline - > extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
/*
if ( ! target_symbol_table ) {
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
*/
2010-04-20 18:57:45 +08:00
if ( OP1_TYPE = = IS_CONST ) {
hash_value = Z_HASH_P ( varname ) ;
2010-04-20 19:05:54 +08:00
} else if ( IS_INTERNED ( Z_STRVAL_P ( varname ) ) ) {
hash_value = INTERNED_HASH ( Z_STRVAL_P ( varname ) ) ;
2010-04-20 18:57:45 +08:00
} else {
hash_value = zend_hash_func ( Z_STRVAL_P ( varname ) , Z_STRLEN_P ( varname ) + 1 ) ;
}
if ( zend_hash_quick_find ( target_symbol_table , Z_STRVAL_P ( varname ) , Z_STRLEN_P ( varname ) + 1 , hash_value , ( void * * ) & retval ) = = FAILURE ) {
2004-10-23 05:42:14 +08:00
switch ( type ) {
case BP_VAR_R :
case BP_VAR_UNSET :
2006-05-12 05:07:39 +08:00
zend_error ( E_NOTICE , " Undefined variable: %s " , Z_STRVAL_P ( varname ) ) ;
2004-10-23 05:42:14 +08:00
/* break missing intentionally */
case BP_VAR_IS :
retval = & EG ( uninitialized_zval_ptr ) ;
break ;
case BP_VAR_RW :
2006-05-12 05:07:39 +08:00
zend_error ( E_NOTICE , " Undefined variable: %s " , Z_STRVAL_P ( varname ) ) ;
2004-10-23 05:42:14 +08:00
/* break missing intentionally */
2010-04-20 19:16:39 +08:00
case BP_VAR_W :
Z_ADDREF_P ( & EG ( uninitialized_zval ) ) ;
zend_hash_quick_update ( target_symbol_table , Z_STRVAL_P ( varname ) , Z_STRLEN_P ( varname ) + 1 , hash_value , & EG ( uninitialized_zval_ptr ) , sizeof ( zval * ) , ( void * * ) & retval ) ;
2004-10-23 05:42:14 +08:00
break ;
EMPTY_SWITCH_DEFAULT_CASE ( )
}
}
2010-04-20 18:57:45 +08:00
switch ( opline - > extended_value & ZEND_FETCH_TYPE_MASK ) {
2004-10-23 05:42:14 +08:00
case ZEND_FETCH_GLOBAL :
2006-05-12 05:07:39 +08:00
if ( OP1_TYPE ! = IS_TMP_VAR ) {
FREE_OP1 ( ) ;
}
break ;
2004-10-23 05:42:14 +08:00
case ZEND_FETCH_LOCAL :
FREE_OP1 ( ) ;
break ;
case ZEND_FETCH_STATIC :
zval_update_constant ( retval , ( void * ) 1 TSRMLS_CC ) ;
break ;
2005-11-30 18:09:37 +08:00
case ZEND_FETCH_GLOBAL_LOCK :
if ( OP1_TYPE = = IS_VAR & & ! free_op1 . var ) {
2010-04-20 18:57:45 +08:00
PZVAL_LOCK ( * EX_T ( opline - > op1 . var ) . var . ptr_ptr ) ;
2005-11-30 18:09:37 +08:00
}
break ;
2004-10-23 05:42:14 +08:00
}
}
2008-01-24 01:55:55 +08:00
if ( OP1_TYPE ! = IS_CONST & & varname = = & tmp_varname ) {
2010-04-20 19:16:39 +08:00
zval_dtor ( & tmp_varname ) ;
2004-10-23 05:42:14 +08:00
}
2010-07-16 21:38:09 +08:00
if ( opline - > extended_value & ZEND_FETCH_MAKE_REF ) {
SEPARATE_ZVAL_TO_MAKE_IS_REF ( retval ) ;
}
PZVAL_LOCK ( * retval ) ;
switch ( type ) {
case BP_VAR_R :
case BP_VAR_IS :
AI_SET_PTR ( & EX_T ( opline - > result . var ) , * retval ) ;
break ;
case BP_VAR_UNSET : {
zend_free_op free_res ;
2004-10-23 05:42:14 +08:00
2010-07-16 21:38:09 +08:00
PZVAL_UNLOCK ( * retval , & free_res ) ;
if ( retval ! = & EG ( uninitialized_zval_ptr ) ) {
SEPARATE_ZVAL_IF_NOT_REF ( retval ) ;
2010-04-20 19:16:39 +08:00
}
2010-07-16 21:38:09 +08:00
PZVAL_LOCK ( * retval ) ;
FREE_OP_VAR_PTR ( free_res ) ;
2004-10-23 05:42:14 +08:00
}
2010-07-16 21:38:09 +08:00
/* break missing intentionally */
default :
EX_T ( opline - > result . var ) . var . ptr_ptr = retval ;
break ;
2004-10-23 05:42:14 +08:00
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2010-05-06 18:27:35 +08:00
ZEND_VM_HANDLER ( 80 , ZEND_FETCH_R , CONST | TMP | VAR | CV , UNUSED | CONST | VAR )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_fetch_var_address_helper , type , BP_VAR_R ) ;
}
2010-05-06 18:27:35 +08:00
ZEND_VM_HANDLER ( 83 , ZEND_FETCH_W , CONST | TMP | VAR | CV , UNUSED | CONST | VAR )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_fetch_var_address_helper , type , BP_VAR_W ) ;
}
2010-05-06 18:27:35 +08:00
ZEND_VM_HANDLER ( 86 , ZEND_FETCH_RW , CONST | TMP | VAR | CV , UNUSED | CONST | VAR )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_fetch_var_address_helper , type , BP_VAR_RW ) ;
}
2010-05-06 18:27:35 +08:00
ZEND_VM_HANDLER ( 92 , ZEND_FETCH_FUNC_ARG , CONST | TMP | VAR | CV , UNUSED | CONST | VAR )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_fetch_var_address_helper , type ,
2012-11-30 17:39:23 +08:00
ARG_SHOULD_BE_SENT_BY_REF ( EX ( call ) - > fbc , ( opline - > extended_value & ZEND_FETCH_ARG_MASK ) ) ? BP_VAR_W : BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
}
2010-05-06 18:27:35 +08:00
ZEND_VM_HANDLER ( 95 , ZEND_FETCH_UNSET , CONST | TMP | VAR | CV , UNUSED | CONST | VAR )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_fetch_var_address_helper , type , BP_VAR_UNSET ) ;
}
2010-05-06 18:27:35 +08:00
ZEND_VM_HANDLER ( 89 , ZEND_FETCH_IS , CONST | TMP | VAR | CV , UNUSED | CONST | VAR )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_fetch_var_address_helper , type , BP_VAR_IS ) ;
}
2012-04-15 11:40:38 +08:00
ZEND_VM_HANDLER ( 81 , ZEND_FETCH_DIM_R , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2008-01-24 01:55:55 +08:00
zval * * container ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
if ( ( opline - > extended_value & ZEND_FETCH_ADD_LOCK ) & &
2006-10-30 19:05:00 +08:00
OP1_TYPE ! = IS_CV & &
2010-04-20 18:57:45 +08:00
EX_T ( opline - > op1 . var ) . var . ptr_ptr ) {
PZVAL_LOCK ( * EX_T ( opline - > op1 . var ) . var . ptr_ptr ) ;
2004-10-23 05:42:14 +08:00
}
2012-08-14 08:59:40 +08:00
if ( OP1_TYPE = = IS_TMP_VAR | | OP1_TYPE = = IS_CONST ) {
zval * container = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
zend_fetch_dimension_address_read ( & EX_T ( opline - > result . var ) , & container , GET_OP2_ZVAL_PTR ( BP_VAR_R ) , OP2_TYPE , BP_VAR_R TSRMLS_CC ) ;
FREE_OP2 ( ) ;
FREE_OP1 ( ) ;
} else {
container = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_R ) ;
zend_fetch_dimension_address_read ( & EX_T ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR ( BP_VAR_R ) , OP2_TYPE , BP_VAR_R TSRMLS_CC ) ;
FREE_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
}
2012-04-15 11:40:38 +08:00
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 84 , ZEND_FETCH_DIM_W , VAR | CV , CONST | TMP | VAR | UNUSED | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
zval * * container ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
container = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_W ) ;
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2008-01-24 01:55:55 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an array " ) ;
}
2010-04-20 19:16:39 +08:00
zend_fetch_dimension_address ( & EX_T ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR ( BP_VAR_R ) , OP2_TYPE , BP_VAR_W TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & OP1_FREE & & READY_TO_DESTROY ( free_op1 . var ) ) {
EXTRACT_ZVAL_PTR ( & EX_T ( opline - > result . var ) ) ;
2006-07-19 17:55:19 +08:00
}
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
2007-10-23 17:55:11 +08:00
/* We are going to assign the result by reference */
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( opline - > extended_value ! = 0 ) ) {
zval * * retval_ptr = EX_T ( opline - > result . var ) . var . ptr_ptr ;
2011-03-16 13:25:02 +08:00
2010-04-20 19:16:39 +08:00
if ( retval_ptr ) {
Z_DELREF_PP ( retval_ptr ) ;
SEPARATE_ZVAL_TO_MAKE_IS_REF ( retval_ptr ) ;
Z_ADDREF_PP ( retval_ptr ) ;
}
2007-10-23 17:55:11 +08:00
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2005-08-10 18:39:55 +08:00
ZEND_VM_HANDLER ( 87 , ZEND_FETCH_DIM_RW , VAR | CV , CONST | TMP | VAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
zval * * container ;
SAVE_OPLINE ( ) ;
container = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2008-01-24 01:55:55 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an array " ) ;
}
2010-04-20 19:16:39 +08:00
zend_fetch_dimension_address ( & EX_T ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR ( BP_VAR_R ) , OP2_TYPE , BP_VAR_RW TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & OP1_FREE & & READY_TO_DESTROY ( free_op1 . var ) ) {
EXTRACT_ZVAL_PTR ( & EX_T ( opline - > result . var ) ) ;
2006-07-19 17:55:19 +08:00
}
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 90 , ZEND_FETCH_DIM_IS , VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
zval * * container ;
SAVE_OPLINE ( ) ;
container = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_IS ) ;
zend_fetch_dimension_address_read ( & EX_T ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR ( BP_VAR_R ) , OP2_TYPE , BP_VAR_IS TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2005-08-10 18:39:55 +08:00
ZEND_VM_HANDLER ( 93 , ZEND_FETCH_DIM_FUNC_ARG , VAR | CV , CONST | TMP | VAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2008-01-24 01:55:55 +08:00
zval * * container ;
2006-05-12 05:07:39 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2012-11-30 17:39:23 +08:00
if ( ARG_SHOULD_BE_SENT_BY_REF ( EX ( call ) - > fbc , ( opline - > extended_value & ZEND_FETCH_ARG_MASK ) ) ) {
2008-01-24 01:55:55 +08:00
container = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2008-01-24 01:55:55 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an array " ) ;
}
2010-04-20 19:16:39 +08:00
zend_fetch_dimension_address ( & EX_T ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR ( BP_VAR_R ) , OP2_TYPE , BP_VAR_W TSRMLS_CC ) ;
if ( OP1_TYPE = = IS_VAR & & OP1_FREE & & READY_TO_DESTROY ( free_op1 . var ) ) {
EXTRACT_ZVAL_PTR ( & EX_T ( opline - > result . var ) ) ;
2007-12-14 22:14:50 +08:00
}
} else {
if ( OP2_TYPE = = IS_UNUSED ) {
zend_error_noreturn ( E_ERROR , " Cannot use [] for reading " ) ;
2007-11-06 22:11:59 +08:00
}
2008-01-24 01:55:55 +08:00
container = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_R ) ;
2010-04-20 19:16:39 +08:00
zend_fetch_dimension_address_read ( & EX_T ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR ( BP_VAR_R ) , OP2_TYPE , BP_VAR_R TSRMLS_CC ) ;
2006-07-19 17:55:19 +08:00
}
2007-12-14 22:14:50 +08:00
FREE_OP2 ( ) ;
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 96 , ZEND_FETCH_DIM_UNSET , VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
zval * * container ;
SAVE_OPLINE ( ) ;
container = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_UNSET ) ;
2004-10-23 05:42:14 +08:00
2005-09-16 22:42:46 +08:00
if ( OP1_TYPE = = IS_CV ) {
if ( container ! = & EG ( uninitialized_zval_ptr ) ) {
SEPARATE_ZVAL_IF_NOT_REF ( container ) ;
}
}
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2008-01-24 01:55:55 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an array " ) ;
}
2010-04-20 19:16:39 +08:00
zend_fetch_dimension_address ( & EX_T ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR ( BP_VAR_R ) , OP2_TYPE , BP_VAR_UNSET TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & OP1_FREE & & READY_TO_DESTROY ( free_op1 . var ) ) {
EXTRACT_ZVAL_PTR ( & EX_T ( opline - > result . var ) ) ;
2006-07-19 17:55:19 +08:00
}
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( EX_T ( opline - > result . var ) . var . ptr_ptr = = NULL ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Cannot unset string offsets " ) ;
2012-12-14 17:21:43 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
2004-10-23 05:42:14 +08:00
} else {
zend_free_op free_res ;
2010-04-20 19:16:39 +08:00
zval * * retval_ptr = EX_T ( opline - > result . var ) . var . ptr_ptr ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
PZVAL_UNLOCK ( * retval_ptr , & free_res ) ;
if ( retval_ptr ! = & EG ( uninitialized_zval_ptr ) ) {
SEPARATE_ZVAL_IF_NOT_REF ( retval_ptr ) ;
2004-10-23 05:42:14 +08:00
}
2010-04-20 19:16:39 +08:00
PZVAL_LOCK ( * retval_ptr ) ;
2004-10-23 05:42:14 +08:00
FREE_OP_VAR_PTR ( free_res ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2004-10-23 05:42:14 +08:00
}
}
2010-04-20 19:16:39 +08:00
ZEND_VM_HELPER ( zend_fetch_property_address_read_helper , VAR | UNUSED | CV , CONST | TMP | VAR | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
zval * container ;
2009-01-15 16:48:58 +08:00
zend_free_op free_op2 ;
2010-04-20 19:16:39 +08:00
zval * offset ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
container = GET_OP1_OBJ_ZVAL_PTR ( BP_VAR_R ) ;
offset = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
if ( UNEXPECTED ( Z_TYPE_P ( container ) ! = IS_OBJECT ) | |
UNEXPECTED ( Z_OBJ_HT_P ( container ) - > read_property = = NULL ) ) {
zend_error ( E_NOTICE , " Trying to get property of non-object " ) ;
2010-07-16 21:38:09 +08:00
PZVAL_LOCK ( & EG ( uninitialized_zval ) ) ;
AI_SET_PTR ( & EX_T ( opline - > result . var ) , & EG ( uninitialized_zval ) ) ;
2009-01-15 16:48:58 +08:00
FREE_OP2 ( ) ;
2004-10-23 05:42:14 +08:00
} else {
2007-12-14 22:14:50 +08:00
zval * retval ;
2004-10-23 05:42:14 +08:00
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
MAKE_REAL_ZVAL_PTR ( offset ) ;
2004-10-23 05:42:14 +08:00
}
/* here we are sure we are dealing with an object */
2010-04-20 19:16:39 +08:00
retval = Z_OBJ_HT_P ( container ) - > read_property ( container , offset , BP_VAR_R , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2010-07-16 21:38:09 +08:00
PZVAL_LOCK ( retval ) ;
AI_SET_PTR ( & EX_T ( opline - > result . var ) , retval ) ;
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
zval_ptr_dtor ( & offset ) ;
} else {
FREE_OP2 ( ) ;
2004-10-23 05:42:14 +08:00
}
}
FREE_OP1 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 82 , ZEND_FETCH_OBJ_R , VAR | UNUSED | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
ZEND_VM_DISPATCH_TO_HELPER ( zend_fetch_property_address_read_helper ) ;
2004-10-23 05:42:14 +08:00
}
ZEND_VM_HANDLER ( 85 , ZEND_FETCH_OBJ_W , VAR | UNUSED | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
zval * property ;
2008-01-24 01:55:55 +08:00
zval * * container ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
property = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2008-01-24 01:55:55 +08:00
if ( OP1_TYPE = = IS_VAR & & ( opline - > extended_value & ZEND_FETCH_ADD_LOCK ) ) {
2010-04-20 18:57:45 +08:00
PZVAL_LOCK ( * EX_T ( opline - > op1 . var ) . var . ptr_ptr ) ;
EX_T ( opline - > op1 . var ) . var . ptr = * EX_T ( opline - > op1 . var ) . var . ptr_ptr ;
2004-10-23 05:42:14 +08:00
}
2011-03-16 13:25:02 +08:00
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
MAKE_REAL_ZVAL_PTR ( property ) ;
}
2008-01-24 01:55:55 +08:00
container = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2008-01-24 16:51:38 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an object " ) ;
2008-01-24 01:55:55 +08:00
}
2010-04-20 19:16:39 +08:00
2010-04-20 18:57:45 +08:00
zend_fetch_property_address ( & EX_T ( opline - > result . var ) , container , property , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) , BP_VAR_W TSRMLS_CC ) ;
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
zval_ptr_dtor ( & property ) ;
} else {
FREE_OP2 ( ) ;
}
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & OP1_FREE & & READY_TO_DESTROY ( free_op1 . var ) ) {
EXTRACT_ZVAL_PTR ( & EX_T ( opline - > result . var ) ) ;
2006-07-19 17:55:19 +08:00
}
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
2007-10-23 20:52:40 +08:00
/* We are going to assign the result by reference */
if ( opline - > extended_value & ZEND_FETCH_MAKE_REF ) {
2010-04-20 19:16:39 +08:00
zval * * retval_ptr = EX_T ( opline - > result . var ) . var . ptr_ptr ;
Z_DELREF_PP ( retval_ptr ) ;
SEPARATE_ZVAL_TO_MAKE_IS_REF ( retval_ptr ) ;
Z_ADDREF_PP ( retval_ptr ) ;
2011-08-01 23:23:16 +08:00
EX_T ( opline - > result . var ) . var . ptr = * EX_T ( opline - > result . var ) . var . ptr_ptr ;
EX_T ( opline - > result . var ) . var . ptr_ptr = & EX_T ( opline - > result . var ) . var . ptr ;
2007-10-23 20:52:40 +08:00
}
2011-03-16 13:25:02 +08:00
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 88 , ZEND_FETCH_OBJ_RW , VAR | UNUSED | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
zval * property ;
zval * * container ;
SAVE_OPLINE ( ) ;
property = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
container = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
2004-10-23 05:42:14 +08:00
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
MAKE_REAL_ZVAL_PTR ( property ) ;
}
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2008-01-24 16:51:38 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an object " ) ;
2008-01-24 01:55:55 +08:00
}
2010-04-20 18:57:45 +08:00
zend_fetch_property_address ( & EX_T ( opline - > result . var ) , container , property , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) , BP_VAR_RW TSRMLS_CC ) ;
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
zval_ptr_dtor ( & property ) ;
} else {
FREE_OP2 ( ) ;
}
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & OP1_FREE & & READY_TO_DESTROY ( free_op1 . var ) ) {
EXTRACT_ZVAL_PTR ( & EX_T ( opline - > result . var ) ) ;
2006-07-19 17:55:19 +08:00
}
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 91 , ZEND_FETCH_OBJ_IS , VAR | UNUSED | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
zend_free_op free_op1 ;
zval * container ;
zend_free_op free_op2 ;
zval * offset ;
SAVE_OPLINE ( ) ;
container = GET_OP1_OBJ_ZVAL_PTR ( BP_VAR_IS ) ;
offset = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
if ( UNEXPECTED ( Z_TYPE_P ( container ) ! = IS_OBJECT ) | |
UNEXPECTED ( Z_OBJ_HT_P ( container ) - > read_property = = NULL ) ) {
2010-07-16 21:38:09 +08:00
PZVAL_LOCK ( & EG ( uninitialized_zval ) ) ;
AI_SET_PTR ( & EX_T ( opline - > result . var ) , & EG ( uninitialized_zval ) ) ;
2010-04-20 19:16:39 +08:00
FREE_OP2 ( ) ;
} else {
zval * retval ;
if ( IS_OP2_TMP_FREE ( ) ) {
MAKE_REAL_ZVAL_PTR ( offset ) ;
}
/* here we are sure we are dealing with an object */
retval = Z_OBJ_HT_P ( container ) - > read_property ( container , offset , BP_VAR_IS , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) TSRMLS_CC ) ;
2010-07-16 21:38:09 +08:00
PZVAL_LOCK ( retval ) ;
AI_SET_PTR ( & EX_T ( opline - > result . var ) , retval ) ;
2010-04-20 19:16:39 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
zval_ptr_dtor ( & offset ) ;
} else {
FREE_OP2 ( ) ;
}
}
FREE_OP1 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2004-10-23 05:42:14 +08:00
}
ZEND_VM_HANDLER ( 94 , ZEND_FETCH_OBJ_FUNC_ARG , VAR | UNUSED | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
2012-11-30 17:39:23 +08:00
if ( ARG_SHOULD_BE_SENT_BY_REF ( EX ( call ) - > fbc , ( opline - > extended_value & ZEND_FETCH_ARG_MASK ) ) ) {
2004-10-23 05:42:14 +08:00
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
zval * property ;
zval * * container ;
SAVE_OPLINE ( ) ;
property = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
container = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2004-10-23 05:42:14 +08:00
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
MAKE_REAL_ZVAL_PTR ( property ) ;
}
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2008-01-24 16:51:38 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an object " ) ;
2008-01-24 01:55:55 +08:00
}
2010-04-20 18:57:45 +08:00
zend_fetch_property_address ( & EX_T ( opline - > result . var ) , container , property , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) , BP_VAR_W TSRMLS_CC ) ;
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
zval_ptr_dtor ( & property ) ;
} else {
FREE_OP2 ( ) ;
}
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & OP1_FREE & & READY_TO_DESTROY ( free_op1 . var ) ) {
EXTRACT_ZVAL_PTR ( & EX_T ( opline - > result . var ) ) ;
2006-07-19 17:55:19 +08:00
}
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
} else {
2010-04-20 19:16:39 +08:00
ZEND_VM_DISPATCH_TO_HELPER ( zend_fetch_property_address_read_helper ) ;
2004-10-23 05:42:14 +08:00
}
}
ZEND_VM_HANDLER ( 97 , ZEND_FETCH_OBJ_UNSET , VAR | UNUSED | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 , free_res ;
2010-04-20 19:16:39 +08:00
zval * * container ;
zval * property ;
SAVE_OPLINE ( ) ;
2010-07-19 23:04:51 +08:00
container = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_UNSET ) ;
2010-04-20 19:16:39 +08:00
property = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2005-09-16 22:42:46 +08:00
if ( OP1_TYPE = = IS_CV ) {
if ( container ! = & EG ( uninitialized_zval_ptr ) ) {
SEPARATE_ZVAL_IF_NOT_REF ( container ) ;
}
}
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
MAKE_REAL_ZVAL_PTR ( property ) ;
}
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2008-01-24 16:51:38 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an object " ) ;
2008-01-24 01:55:55 +08:00
}
2010-04-20 18:57:45 +08:00
zend_fetch_property_address ( & EX_T ( opline - > result . var ) , container , property , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) , BP_VAR_UNSET TSRMLS_CC ) ;
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
zval_ptr_dtor ( & property ) ;
} else {
FREE_OP2 ( ) ;
}
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & OP1_FREE & & READY_TO_DESTROY ( free_op1 . var ) ) {
EXTRACT_ZVAL_PTR ( & EX_T ( opline - > result . var ) ) ;
2006-07-19 17:55:19 +08:00
}
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 18:57:45 +08:00
PZVAL_UNLOCK ( * EX_T ( opline - > result . var ) . var . ptr_ptr , & free_res ) ;
if ( EX_T ( opline - > result . var ) . var . ptr_ptr ! = & EG ( uninitialized_zval_ptr ) ) {
SEPARATE_ZVAL_IF_NOT_REF ( EX_T ( opline - > result . var ) . var . ptr_ptr ) ;
2004-10-23 05:42:14 +08:00
}
2010-04-20 18:57:45 +08:00
PZVAL_LOCK ( * EX_T ( opline - > result . var ) . var . ptr_ptr ) ;
2004-10-23 05:42:14 +08:00
FREE_OP_VAR_PTR ( free_res ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2007-02-26 00:02:43 +08:00
ZEND_VM_HANDLER ( 98 , ZEND_FETCH_DIM_TMP_VAR , CONST | TMP , CONST )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
zval * container ;
SAVE_OPLINE ( ) ;
container = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( container ) ! = IS_ARRAY ) ) {
2010-07-16 21:38:09 +08:00
PZVAL_LOCK ( & EG ( uninitialized_zval ) ) ;
AI_SET_PTR ( & EX_T ( opline - > result . var ) , & EG ( uninitialized_zval ) ) ;
2004-10-23 05:42:14 +08:00
} else {
zend_free_op free_op2 ;
2010-04-20 19:16:39 +08:00
zval * value = * zend_fetch_dimension_address_inner ( Z_ARRVAL_P ( container ) , GET_OP2_ZVAL_PTR ( BP_VAR_R ) , OP2_TYPE , BP_VAR_R TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2010-07-26 20:40:32 +08:00
PZVAL_LOCK ( value ) ;
2010-04-20 19:16:39 +08:00
AI_SET_PTR ( & EX_T ( opline - > result . var ) , value ) ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 136 , ZEND_ASSIGN_OBJ , VAR | UNUSED | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2007-12-14 22:14:50 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
zval * * object_ptr ;
zval * property_name ;
SAVE_OPLINE ( ) ;
object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_W ) ;
property_name = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2007-12-14 22:14:50 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
MAKE_REAL_ZVAL_PTR ( property_name ) ;
}
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( object_ptr = = NULL ) ) {
2008-01-24 01:55:55 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an array " ) ;
}
2012-12-04 14:14:39 +08:00
zend_assign_to_object ( RETURN_VALUE_USED ( opline ) ? & EX_T ( opline - > result . var ) . var . ptr : NULL , object_ptr , property_name , ( opline + 1 ) - > op1_type , & ( opline + 1 ) - > op1 , execute_data , ZEND_ASSIGN_OBJ , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) TSRMLS_CC ) ;
2007-12-14 22:14:50 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
zval_ptr_dtor ( & property_name ) ;
} else {
FREE_OP2 ( ) ;
}
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
/* assign_obj has two opcodes! */
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_INC_OPCODE ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2006-09-04 21:58:54 +08:00
ZEND_VM_HANDLER ( 147 , ZEND_ASSIGN_DIM , VAR | CV , CONST | TMP | VAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
zval * * object_ptr ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
object_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_W ) ;
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( object_ptr = = NULL ) ) {
2009-03-18 20:53:17 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an array " ) ;
2004-10-23 05:42:14 +08:00
}
2009-03-18 20:53:17 +08:00
if ( Z_TYPE_PP ( object_ptr ) = = IS_OBJECT ) {
2007-12-14 22:14:50 +08:00
zend_free_op free_op2 ;
zval * property_name = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
if ( IS_OP2_TMP_FREE ( ) ) {
MAKE_REAL_ZVAL_PTR ( property_name ) ;
}
2012-12-04 14:14:39 +08:00
zend_assign_to_object ( RETURN_VALUE_USED ( opline ) ? & EX_T ( opline - > result . var ) . var . ptr : NULL , object_ptr , property_name , ( opline + 1 ) - > op1_type , & ( opline + 1 ) - > op1 , execute_data , ZEND_ASSIGN_DIM , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) TSRMLS_CC ) ;
2007-12-14 22:14:50 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
zval_ptr_dtor ( & property_name ) ;
} else {
FREE_OP2 ( ) ;
}
2004-10-23 05:42:14 +08:00
} else {
2007-12-14 22:14:50 +08:00
zend_free_op free_op2 , free_op_data1 , free_op_data2 ;
2004-10-23 05:42:14 +08:00
zval * value ;
2005-06-03 19:16:19 +08:00
zval * dim = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2007-12-14 22:14:50 +08:00
zval * * variable_ptr_ptr ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
zend_fetch_dimension_address ( & EX_T ( ( opline + 1 ) - > op2 . var ) , object_ptr , dim , OP2_TYPE , BP_VAR_W TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2012-12-04 14:14:39 +08:00
value = get_zval_ptr ( ( opline + 1 ) - > op1_type , & ( opline + 1 ) - > op1 , execute_data , & free_op_data1 , BP_VAR_R ) ;
variable_ptr_ptr = _get_zval_ptr_ptr_var ( ( opline + 1 ) - > op2 . var , execute_data , & free_op_data2 TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( variable_ptr_ptr = = NULL ) ) {
if ( zend_assign_to_string_offset ( & EX_T ( ( opline + 1 ) - > op2 . var ) , value , ( opline + 1 ) - > op1_type TSRMLS_CC ) ) {
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2010-04-20 19:16:39 +08:00
zval * retval ;
ALLOC_ZVAL ( retval ) ;
ZVAL_STRINGL ( retval , Z_STRVAL_P ( EX_T ( ( opline + 1 ) - > op2 . var ) . str_offset . str ) + EX_T ( ( opline + 1 ) - > op2 . var ) . str_offset . offset , 1 , 1 ) ;
INIT_PZVAL ( retval ) ;
AI_SET_PTR ( & EX_T ( opline - > result . var ) , retval ) ;
2008-03-04 18:06:52 +08:00
}
2010-04-20 18:57:45 +08:00
} else if ( RETURN_VALUE_USED ( opline ) ) {
2010-04-20 19:16:39 +08:00
PZVAL_LOCK ( & EG ( uninitialized_zval ) ) ;
AI_SET_PTR ( & EX_T ( opline - > result . var ) , & EG ( uninitialized_zval ) ) ;
}
} else if ( UNEXPECTED ( * variable_ptr_ptr = = & EG ( error_zval ) ) ) {
if ( IS_TMP_FREE ( free_op_data1 ) ) {
zval_dtor ( value ) ;
}
if ( RETURN_VALUE_USED ( opline ) ) {
PZVAL_LOCK ( & EG ( uninitialized_zval ) ) ;
AI_SET_PTR ( & EX_T ( opline - > result . var ) , & EG ( uninitialized_zval ) ) ;
2008-03-04 18:06:52 +08:00
}
2007-12-14 22:14:50 +08:00
} else {
2010-08-11 23:34:06 +08:00
if ( ( opline + 1 ) - > op1_type = = IS_TMP_VAR ) {
2010-04-20 19:16:39 +08:00
value = zend_assign_tmp_to_variable ( variable_ptr_ptr , value TSRMLS_CC ) ;
2010-08-11 23:34:06 +08:00
} else if ( ( opline + 1 ) - > op1_type = = IS_CONST ) {
value = zend_assign_const_to_variable ( variable_ptr_ptr , value TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
} else {
value = zend_assign_to_variable ( variable_ptr_ptr , value TSRMLS_CC ) ;
}
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2008-03-04 18:06:52 +08:00
PZVAL_LOCK ( value ) ;
2010-04-20 19:16:39 +08:00
AI_SET_PTR ( & EX_T ( opline - > result . var ) , value ) ;
2008-03-04 18:06:52 +08:00
}
2007-12-14 22:14:50 +08:00
}
FREE_OP_VAR_PTR ( free_op_data2 ) ;
2004-10-23 05:42:14 +08:00
FREE_OP_IF_VAR ( free_op_data1 ) ;
}
FREE_OP1_VAR_PTR ( ) ;
/* assign_dim has two opcodes! */
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_INC_OPCODE ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 38 , ZEND_ASSIGN , VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2007-12-14 22:14:50 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
zval * value ;
zval * * variable_ptr_ptr ;
2007-12-14 22:14:50 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
value = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
variable_ptr_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_W ) ;
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( variable_ptr_ptr = = NULL ) ) {
2010-04-20 18:57:45 +08:00
if ( zend_assign_to_string_offset ( & EX_T ( opline - > op1 . var ) , value , OP2_TYPE TSRMLS_CC ) ) {
if ( RETURN_VALUE_USED ( opline ) ) {
2010-04-20 19:16:39 +08:00
zval * retval ;
ALLOC_ZVAL ( retval ) ;
ZVAL_STRINGL ( retval , Z_STRVAL_P ( EX_T ( opline - > op1 . var ) . str_offset . str ) + EX_T ( opline - > op1 . var ) . str_offset . offset , 1 , 1 ) ;
INIT_PZVAL ( retval ) ;
AI_SET_PTR ( & EX_T ( opline - > result . var ) , retval ) ;
2008-03-04 18:06:52 +08:00
}
2010-04-20 18:57:45 +08:00
} else if ( RETURN_VALUE_USED ( opline ) ) {
2010-04-20 19:16:39 +08:00
PZVAL_LOCK ( & EG ( uninitialized_zval ) ) ;
AI_SET_PTR ( & EX_T ( opline - > result . var ) , & EG ( uninitialized_zval ) ) ;
}
} else if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( * variable_ptr_ptr = = & EG ( error_zval ) ) ) {
if ( IS_OP2_TMP_FREE ( ) ) {
zval_dtor ( value ) ;
}
if ( RETURN_VALUE_USED ( opline ) ) {
PZVAL_LOCK ( & EG ( uninitialized_zval ) ) ;
AI_SET_PTR ( & EX_T ( opline - > result . var ) , & EG ( uninitialized_zval ) ) ;
2008-03-04 18:06:52 +08:00
}
2007-12-14 22:14:50 +08:00
} else {
2010-08-11 23:34:06 +08:00
if ( OP2_TYPE = = IS_TMP_VAR ) {
2010-04-20 19:16:39 +08:00
value = zend_assign_tmp_to_variable ( variable_ptr_ptr , value TSRMLS_CC ) ;
2010-08-11 23:34:06 +08:00
} else if ( OP2_TYPE = = IS_CONST ) {
value = zend_assign_const_to_variable ( variable_ptr_ptr , value TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
} else {
value = zend_assign_to_variable ( variable_ptr_ptr , value TSRMLS_CC ) ;
}
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2008-03-04 18:06:52 +08:00
PZVAL_LOCK ( value ) ;
2010-04-20 19:16:39 +08:00
AI_SET_PTR ( & EX_T ( opline - > result . var ) , value ) ;
2008-03-04 18:06:52 +08:00
}
2007-12-14 22:14:50 +08:00
}
FREE_OP1_VAR_PTR ( ) ;
2004-10-23 05:42:14 +08:00
/* zend_assign_to_variable() always takes care of op2, never free it! */
FREE_OP2_IF_VAR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 39 , ZEND_ASSIGN_REF , VAR | CV , VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2005-05-06 01:37:25 +08:00
zval * * variable_ptr_ptr ;
2010-04-20 19:16:39 +08:00
zval * * value_ptr_ptr ;
SAVE_OPLINE ( ) ;
value_ptr_ptr = GET_OP2_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2004-10-23 05:42:14 +08:00
2005-05-06 01:37:25 +08:00
if ( OP2_TYPE = = IS_VAR & &
2005-06-27 14:15:35 +08:00
value_ptr_ptr & &
2007-10-07 13:22:07 +08:00
! Z_ISREF_PP ( value_ptr_ptr ) & &
2006-05-12 05:07:39 +08:00
opline - > extended_value = = ZEND_RETURNS_FUNCTION & &
2010-04-20 18:57:45 +08:00
! EX_T ( opline - > op2 . var ) . var . fcall_returned_reference ) {
2005-05-06 01:37:25 +08:00
if ( free_op2 . var = = NULL ) {
PZVAL_LOCK ( * value_ptr_ptr ) ; /* undo the effect of get_zval_ptr_ptr() */
}
2005-06-07 18:01:30 +08:00
zend_error ( E_STRICT , " Only variables should be assigned by reference " ) ;
2008-08-13 15:21:30 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
FREE_OP2_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
HANDLE_EXCEPTION ( ) ;
2008-08-13 15:21:30 +08:00
}
2005-05-06 01:37:25 +08:00
ZEND_VM_DISPATCH_TO_HANDLER ( ZEND_ASSIGN ) ;
2008-07-24 19:47:51 +08:00
} else if ( OP2_TYPE = = IS_VAR & & opline - > extended_value = = ZEND_RETURNS_NEW ) {
PZVAL_LOCK ( * value_ptr_ptr ) ;
2005-05-06 01:37:25 +08:00
}
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( EX_T ( opline - > op1 . var ) . var . ptr_ptr = = & EX_T ( opline - > op1 . var ) . var . ptr ) ) {
2009-03-19 02:49:27 +08:00
zend_error_noreturn ( E_ERROR , " Cannot assign by reference to overloaded object " ) ;
2005-06-23 19:04:35 +08:00
}
2005-05-06 01:37:25 +08:00
variable_ptr_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2010-04-20 19:16:39 +08:00
if ( ( OP2_TYPE = = IS_VAR & & UNEXPECTED ( value_ptr_ptr = = NULL ) ) | |
( OP1_TYPE = = IS_VAR & & UNEXPECTED ( variable_ptr_ptr = = NULL ) ) ) {
2008-01-24 01:55:55 +08:00
zend_error_noreturn ( E_ERROR , " Cannot create references to/from string offsets nor overloaded objects " ) ;
}
2004-10-23 05:42:14 +08:00
zend_assign_to_variable_reference ( variable_ptr_ptr , value_ptr_ptr TSRMLS_CC ) ;
2008-07-24 19:47:51 +08:00
if ( OP2_TYPE = = IS_VAR & & opline - > extended_value = = ZEND_RETURNS_NEW ) {
Z_DELREF_PP ( variable_ptr_ptr ) ;
}
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2004-10-23 05:42:14 +08:00
PZVAL_LOCK ( * variable_ptr_ptr ) ;
2010-04-20 19:16:39 +08:00
AI_SET_PTR ( & EX_T ( opline - > result . var ) , * variable_ptr_ptr ) ;
2004-10-23 05:42:14 +08:00
}
FREE_OP1_VAR_PTR ( ) ;
FREE_OP2_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2012-08-22 18:32:03 +08:00
ZEND_VM_HELPER ( zend_leave_helper , ANY , ANY )
2004-10-23 05:42:14 +08:00
{
2012-12-21 08:56:37 +08:00
zend_bool nested = EX ( nested ) ;
2012-08-22 18:32:03 +08:00
zend_op_array * op_array = EX ( op_array ) ;
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
EG ( current_execute_data ) = EX ( prev_execute_data ) ;
EG ( opline_ptr ) = NULL ;
if ( ! EG ( active_symbol_table ) ) {
2012-12-05 17:23:37 +08:00
i_free_compiled_variables ( execute_data ) ;
2012-08-22 18:32:03 +08:00
}
2004-10-23 05:42:14 +08:00
2012-12-21 08:56:37 +08:00
zend_vm_stack_free ( ( char * ) execute_data - ( ZEND_MM_ALIGNED_SIZE ( sizeof ( temp_variable ) ) * op_array - > T ) TSRMLS_CC ) ;
2012-08-22 18:32:03 +08:00
if ( ( op_array - > fn_flags & ZEND_ACC_CLOSURE ) & & op_array - > prototype ) {
zval_ptr_dtor ( ( zval * * ) & op_array - > prototype ) ;
}
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
if ( nested ) {
execute_data = EG ( current_execute_data ) ;
2004-10-23 05:42:14 +08:00
}
2012-08-22 18:32:03 +08:00
if ( nested ) {
USE_OPLINE
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
LOAD_REGS ( ) ;
LOAD_OPLINE ( ) ;
if ( UNEXPECTED ( opline - > opcode = = ZEND_INCLUDE_OR_EVAL ) ) {
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
EX ( function_state ) . function = ( zend_function * ) EX ( op_array ) ;
EX ( function_state ) . arguments = NULL ;
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
EG ( opline_ptr ) = & EX ( opline ) ;
EG ( active_op_array ) = EX ( op_array ) ;
EG ( return_value_ptr_ptr ) = EX ( original_return_value ) ;
destroy_op_array ( op_array TSRMLS_CC ) ;
efree ( op_array ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
zend_throw_exception_internal ( NULL TSRMLS_CC ) ;
HANDLE_EXCEPTION_LEAVE ( ) ;
}
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
ZEND_VM_INC_OPCODE ( ) ;
ZEND_VM_LEAVE ( ) ;
} else {
EG ( opline_ptr ) = & EX ( opline ) ;
EG ( active_op_array ) = EX ( op_array ) ;
EG ( return_value_ptr_ptr ) = EX ( original_return_value ) ;
if ( EG ( active_symbol_table ) ) {
2012-08-24 19:29:40 +08:00
zend_clean_and_cache_symbol_table ( EG ( active_symbol_table ) TSRMLS_CC ) ;
2012-08-22 18:32:03 +08:00
}
EG ( active_symbol_table ) = EX ( symbol_table ) ;
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
EX ( function_state ) . function = ( zend_function * ) EX ( op_array ) ;
EX ( function_state ) . arguments = NULL ;
2010-04-20 19:16:39 +08:00
2012-08-22 18:32:03 +08:00
if ( EG ( This ) ) {
2012-11-30 17:39:23 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) & & EX ( call ) - > is_ctor_call ) {
if ( EX ( call ) - > is_ctor_result_used ) {
2012-08-22 18:32:03 +08:00
Z_DELREF_P ( EG ( This ) ) ;
}
if ( Z_REFCOUNT_P ( EG ( This ) ) = = 1 ) {
zend_object_store_ctor_failed ( EG ( This ) TSRMLS_CC ) ;
}
}
zval_ptr_dtor ( & EG ( This ) ) ;
}
EG ( This ) = EX ( current_this ) ;
EG ( scope ) = EX ( current_scope ) ;
EG ( called_scope ) = EX ( current_called_scope ) ;
2004-10-23 05:42:14 +08:00
2012-11-30 17:39:23 +08:00
EX ( call ) - - ;
2004-10-23 05:42:14 +08:00
2012-12-13 21:29:30 +08:00
zend_vm_stack_clear_multiple ( 1 TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
2012-08-22 18:32:03 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
zend_throw_exception_internal ( NULL TSRMLS_CC ) ;
if ( RETURN_VALUE_USED ( opline ) & & EX_T ( opline - > result . var ) . var . ptr ) {
zval_ptr_dtor ( & EX_T ( opline - > result . var ) . var . ptr ) ;
}
HANDLE_EXCEPTION_LEAVE ( ) ;
}
ZEND_VM_INC_OPCODE ( ) ;
ZEND_VM_LEAVE ( ) ;
2009-03-18 22:17:15 +08:00
}
}
2012-08-22 18:32:03 +08:00
ZEND_VM_RETURN ( ) ;
2004-10-23 05:42:14 +08:00
}
2012-08-22 18:32:03 +08:00
ZEND_VM_HELPER ( zend_do_fcall_common_helper , ANY , ANY )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2012-08-22 18:32:03 +08:00
zend_bool should_change_scope = 0 ;
zend_function * fbc = EX ( function_state ) . function ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2012-11-30 17:39:23 +08:00
EX ( object ) = EX ( call ) - > object ;
2012-08-22 18:32:03 +08:00
if ( UNEXPECTED ( ( fbc - > common . fn_flags & ( ZEND_ACC_ABSTRACT | ZEND_ACC_DEPRECATED ) ) ! = 0 ) ) {
if ( UNEXPECTED ( ( fbc - > common . fn_flags & ZEND_ACC_ABSTRACT ) ! = 0 ) ) {
zend_error_noreturn ( E_ERROR , " Cannot call abstract method %s::%s() " , fbc - > common . scope - > name , fbc - > common . function_name ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ; /* Never reached */
}
if ( UNEXPECTED ( ( fbc - > common . fn_flags & ZEND_ACC_DEPRECATED ) ! = 0 ) ) {
zend_error ( E_DEPRECATED , " Function %s%s%s() is deprecated " ,
fbc - > common . scope ? fbc - > common . scope - > name : " " ,
fbc - > common . scope ? " :: " : " " ,
fbc - > common . function_name ) ;
}
2010-07-16 21:38:09 +08:00
}
2012-08-22 18:32:03 +08:00
if ( fbc - > common . scope & &
! ( fbc - > common . fn_flags & ZEND_ACC_STATIC ) & &
! EX ( object ) ) {
2010-04-20 19:16:39 +08:00
2012-08-22 18:32:03 +08:00
if ( fbc - > common . fn_flags & ZEND_ACC_ALLOW_STATIC ) {
/* FIXME: output identifiers properly */
zend_error ( E_STRICT , " Non-static method %s::%s() should not be called statically " , fbc - > common . scope - > name , fbc - > common . function_name ) ;
} else {
/* FIXME: output identifiers properly */
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
zend_error_noreturn ( E_ERROR , " Non-static method %s::%s() cannot be called statically " , fbc - > common . scope - > name , fbc - > common . function_name ) ;
2009-03-18 22:17:15 +08:00
}
}
2008-07-26 23:30:28 +08:00
2012-08-22 18:32:03 +08:00
if ( fbc - > type = = ZEND_USER_FUNCTION | | fbc - > common . scope ) {
should_change_scope = 1 ;
EX ( current_this ) = EG ( This ) ;
EX ( current_scope ) = EG ( scope ) ;
EX ( current_called_scope ) = EG ( called_scope ) ;
EG ( This ) = EX ( object ) ;
EG ( scope ) = ( fbc - > type = = ZEND_USER_FUNCTION | | ! EX ( object ) ) ? fbc - > common . scope : NULL ;
2012-11-30 17:39:23 +08:00
EG ( called_scope ) = EX ( call ) - > called_scope ;
2008-07-26 23:30:28 +08:00
}
2012-11-30 17:39:23 +08:00
EX ( function_state ) . arguments = zend_vm_stack_top ( TSRMLS_C ) ;
zend_vm_stack_push ( ( void * ) ( zend_uintptr_t ) opline - > extended_value TSRMLS_CC ) ;
2012-08-22 18:32:03 +08:00
LOAD_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
if ( fbc - > type = = ZEND_INTERNAL_FUNCTION ) {
temp_variable * ret = & EX_T ( opline - > result . var ) ;
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
MAKE_STD_ZVAL ( ret - > var . ptr ) ;
ZVAL_NULL ( ret - > var . ptr ) ;
ret - > var . ptr_ptr = & ret - > var . ptr ;
ret - > var . fcall_returned_reference = ( fbc - > common . fn_flags & ZEND_ACC_RETURN_REFERENCE ) ! = 0 ;
if ( fbc - > common . arg_info ) {
zend_uint i = 0 ;
zval * * p = ( zval * * ) EX ( function_state ) . arguments ;
ulong arg_count = opline - > extended_value ;
2008-07-26 23:30:28 +08:00
2012-08-22 18:32:03 +08:00
while ( arg_count > 0 ) {
zend_verify_arg_type ( fbc , + + i , * ( p - arg_count ) , 0 TSRMLS_CC ) ;
arg_count - - ;
}
}
2010-04-20 19:16:39 +08:00
2012-08-22 18:32:03 +08:00
if ( ! zend_execute_internal ) {
/* saves one function call if zend_execute_internal is not used */
fbc - > internal_function . handler ( opline - > extended_value , ret - > var . ptr , ( fbc - > common . fn_flags & ZEND_ACC_RETURN_REFERENCE ) ? & ret - > var . ptr : NULL , EX ( object ) , RETURN_VALUE_USED ( opline ) TSRMLS_CC ) ;
} else {
2012-12-04 14:14:39 +08:00
zend_execute_internal ( execute_data , NULL , RETURN_VALUE_USED ( opline ) TSRMLS_CC ) ;
2012-08-22 18:32:03 +08:00
}
2008-07-26 23:30:28 +08:00
2012-08-22 18:32:03 +08:00
if ( ! RETURN_VALUE_USED ( opline ) ) {
zval_ptr_dtor ( & ret - > var . ptr ) ;
}
} else if ( fbc - > type = = ZEND_USER_FUNCTION ) {
EX ( original_return_value ) = EG ( return_value_ptr_ptr ) ;
EG ( active_symbol_table ) = NULL ;
EG ( active_op_array ) = & fbc - > op_array ;
EG ( return_value_ptr_ptr ) = NULL ;
if ( RETURN_VALUE_USED ( opline ) ) {
temp_variable * ret = & EX_T ( opline - > result . var ) ;
2008-07-26 23:30:28 +08:00
2012-08-22 18:32:03 +08:00
ret - > var . ptr = NULL ;
EG ( return_value_ptr_ptr ) = & ret - > var . ptr ;
ret - > var . ptr_ptr = & ret - > var . ptr ;
ret - > var . fcall_returned_reference = ( fbc - > common . fn_flags & ZEND_ACC_RETURN_REFERENCE ) ! = 0 ;
}
2004-10-23 05:42:14 +08:00
2012-12-06 17:14:31 +08:00
if ( UNEXPECTED ( ( EG ( active_op_array ) - > fn_flags & ZEND_ACC_GENERATOR ) ! = 0 ) ) {
2012-08-24 19:29:40 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
EX_T ( opline - > result . var ) . var . ptr = zend_generator_create_zval ( EG ( active_op_array ) TSRMLS_CC ) ;
}
2012-11-30 17:39:23 +08:00
} else if ( EXPECTED ( zend_execute_ex = = execute_ex ) ) {
2012-08-22 18:32:03 +08:00
if ( EXPECTED ( EG ( exception ) = = NULL ) ) {
ZEND_VM_ENTER ( ) ;
}
} else {
zend_execute ( EG ( active_op_array ) TSRMLS_CC ) ;
}
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
EG ( opline_ptr ) = & EX ( opline ) ;
EG ( active_op_array ) = EX ( op_array ) ;
EG ( return_value_ptr_ptr ) = EX ( original_return_value ) ;
if ( EG ( active_symbol_table ) ) {
2012-08-24 19:29:40 +08:00
zend_clean_and_cache_symbol_table ( EG ( active_symbol_table ) TSRMLS_CC ) ;
2012-08-22 18:32:03 +08:00
}
EG ( active_symbol_table ) = EX ( symbol_table ) ;
} else { /* ZEND_OVERLOADED_FUNCTION */
MAKE_STD_ZVAL ( EX_T ( opline - > result . var ) . var . ptr ) ;
ZVAL_NULL ( EX_T ( opline - > result . var ) . var . ptr ) ;
2004-10-23 05:42:14 +08:00
2012-08-24 19:29:40 +08:00
/* Not sure what should be done here if it's a static method */
2012-08-22 18:32:03 +08:00
if ( EXPECTED ( EX ( object ) ! = NULL ) ) {
Z_OBJ_HT_P ( EX ( object ) ) - > call_method ( fbc - > common . function_name , opline - > extended_value , EX_T ( opline - > result . var ) . var . ptr , & EX_T ( opline - > result . var ) . var . ptr , EX ( object ) , RETURN_VALUE_USED ( opline ) TSRMLS_CC ) ;
} else {
zend_error_noreturn ( E_ERROR , " Cannot call overloaded function for non-object " ) ;
}
2011-03-16 13:25:02 +08:00
2012-08-22 18:32:03 +08:00
if ( fbc - > type = = ZEND_OVERLOADED_FUNCTION_TEMPORARY ) {
efree ( ( char * ) fbc - > common . function_name ) ;
}
efree ( fbc ) ;
2008-07-26 23:30:28 +08:00
2012-08-22 18:32:03 +08:00
if ( ! RETURN_VALUE_USED ( opline ) ) {
zval_ptr_dtor ( & EX_T ( opline - > result . var ) . var . ptr ) ;
} else {
Z_UNSET_ISREF_P ( EX_T ( opline - > result . var ) . var . ptr ) ;
Z_SET_REFCOUNT_P ( EX_T ( opline - > result . var ) . var . ptr , 1 ) ;
EX_T ( opline - > result . var ) . var . fcall_returned_reference = 0 ;
EX_T ( opline - > result . var ) . var . ptr_ptr = & EX_T ( opline - > result . var ) . var . ptr ;
2009-03-18 22:17:15 +08:00
}
2008-07-26 23:30:28 +08:00
}
2012-08-22 18:32:03 +08:00
EX ( function_state ) . function = ( zend_function * ) EX ( op_array ) ;
EX ( function_state ) . arguments = NULL ;
2007-05-18 21:12:05 +08:00
2012-08-22 18:32:03 +08:00
if ( should_change_scope ) {
if ( EG ( This ) ) {
2012-11-30 17:39:23 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) & & EX ( call ) - > is_ctor_call ) {
if ( EX ( call ) - > is_ctor_result_used ) {
2012-08-22 18:32:03 +08:00
Z_DELREF_P ( EG ( This ) ) ;
}
if ( Z_REFCOUNT_P ( EG ( This ) ) = = 1 ) {
zend_object_store_ctor_failed ( EG ( This ) TSRMLS_CC ) ;
}
}
zval_ptr_dtor ( & EG ( This ) ) ;
2007-05-18 21:12:05 +08:00
}
2012-08-22 18:32:03 +08:00
EG ( This ) = EX ( current_this ) ;
EG ( scope ) = EX ( current_scope ) ;
EG ( called_scope ) = EX ( current_called_scope ) ;
2004-10-23 05:42:14 +08:00
}
2008-07-26 23:30:28 +08:00
2012-11-30 17:39:23 +08:00
EX ( call ) - - ;
2012-08-22 18:32:03 +08:00
2012-12-13 21:29:30 +08:00
zend_vm_stack_clear_multiple ( 1 TSRMLS_CC ) ;
2012-08-22 18:32:03 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
zend_throw_exception_internal ( NULL TSRMLS_CC ) ;
if ( RETURN_VALUE_USED ( opline ) & & EX_T ( opline - > result . var ) . var . ptr ) {
zval_ptr_dtor ( & EX_T ( opline - > result . var ) . var . ptr ) ;
}
HANDLE_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
ZEND_VM_NEXT_OPCODE ( ) ;
}
2012-08-22 18:32:03 +08:00
ZEND_VM_HANDLER ( 42 , ZEND_JMP , ANY , ANY )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
# if DEBUG_ZEND>=2
printf ( " Jumping to %d \n " , opline - > op1 . opline_num ) ;
# endif
2012-11-22 19:17:05 +08:00
ZEND_VM_SET_OPCODE ( opline - > op1 . jmp_addr ) ;
ZEND_VM_CONTINUE ( ) ;
2004-10-23 05:42:14 +08:00
}
2012-08-22 18:32:03 +08:00
ZEND_VM_HANDLER ( 43 , ZEND_JMPZ , CONST | TMP | VAR | CV , ANY )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2012-08-22 18:32:03 +08:00
zend_free_op free_op1 ;
zval * val ;
int ret ;
2010-05-24 22:11:39 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2012-08-22 18:32:03 +08:00
val = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2011-03-16 13:25:02 +08:00
2012-08-22 18:32:03 +08:00
if ( OP1_TYPE = = IS_TMP_VAR & & EXPECTED ( Z_TYPE_P ( val ) = = IS_BOOL ) ) {
ret = Z_LVAL_P ( val ) ;
2011-03-16 13:25:02 +08:00
} else {
2012-08-22 18:32:03 +08:00
ret = i_zend_is_true ( val ) ;
FREE_OP1 ( ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
}
2012-08-22 18:32:03 +08:00
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 ( ) ;
2008-07-26 23:30:28 +08:00
}
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2012-08-22 18:32:03 +08:00
ZEND_VM_HANDLER ( 44 , ZEND_JMPNZ , CONST | TMP | VAR | CV , ANY )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2012-08-22 18:32:03 +08:00
zend_free_op free_op1 ;
zval * val ;
int ret ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2012-08-22 18:32:03 +08:00
val = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
if ( OP1_TYPE = = IS_TMP_VAR & & EXPECTED ( Z_TYPE_P ( val ) = = IS_BOOL ) ) {
ret = Z_LVAL_P ( val ) ;
2007-09-29 03:52:53 +08:00
} else {
2012-08-22 18:32:03 +08:00
ret = i_zend_is_true ( val ) ;
FREE_OP1 ( ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
2008-07-24 17:42:18 +08:00
}
2007-09-29 03:52:53 +08:00
}
2012-08-22 18:32:03 +08:00
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 ( ) ;
}
2010-05-24 22:11:39 +08:00
2012-08-22 18:32:03 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
ZEND_VM_HANDLER ( 45 , ZEND_JMPZNZ , CONST | TMP | VAR | CV , ANY )
{
USE_OPLINE
zend_free_op free_op1 ;
zval * val ;
int retval ;
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
SAVE_OPLINE ( ) ;
val = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
if ( OP1_TYPE = = IS_TMP_VAR & & EXPECTED ( Z_TYPE_P ( val ) = = IS_BOOL ) ) {
retval = Z_LVAL_P ( val ) ;
2004-10-23 05:42:14 +08:00
} else {
2012-08-22 18:32:03 +08:00
retval = i_zend_is_true ( val ) ;
FREE_OP1 ( ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
2006-08-08 07:24:33 +08:00
}
2004-10-23 05:42:14 +08:00
}
2012-08-22 18:32:03 +08:00
if ( EXPECTED ( retval ! = 0 ) ) {
# if DEBUG_ZEND>=2
printf ( " Conditional jmp on true to %d \n " , opline - > extended_value ) ;
# endif
ZEND_VM_SET_OPCODE ( & EX ( op_array ) - > opcodes [ opline - > extended_value ] ) ;
ZEND_VM_CONTINUE ( ) ; /* CHECK_ME */
} else {
# if DEBUG_ZEND>=2
printf ( " Conditional jmp on false to %d \n " , opline - > op2 . opline_num ) ;
# endif
ZEND_VM_SET_OPCODE ( & EX ( op_array ) - > opcodes [ opline - > op2 . opline_num ] ) ;
ZEND_VM_CONTINUE ( ) ; /* CHECK_ME */
}
}
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
ZEND_VM_HANDLER ( 46 , ZEND_JMPZ_EX , CONST | TMP | VAR | CV , ANY )
{
USE_OPLINE
zend_free_op free_op1 ;
zval * val ;
int retval ;
SAVE_OPLINE ( ) ;
val = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
if ( OP1_TYPE = = IS_TMP_VAR & & EXPECTED ( Z_TYPE_P ( val ) = = IS_BOOL ) ) {
retval = Z_LVAL_P ( val ) ;
2004-10-23 05:42:14 +08:00
} else {
2012-08-22 18:32:03 +08:00
retval = i_zend_is_true ( val ) ;
FREE_OP1 ( ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
}
2012-08-22 18:32:03 +08:00
Z_LVAL ( EX_T ( opline - > result . var ) . tmp_var ) = retval ;
Z_TYPE ( EX_T ( opline - > result . var ) . tmp_var ) = IS_BOOL ;
if ( ! retval ) {
# 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 ( ) ;
}
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2012-08-22 18:32:03 +08:00
ZEND_VM_HANDLER ( 47 , ZEND_JMPNZ_EX , CONST | TMP | VAR | CV , ANY )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2012-08-22 18:32:03 +08:00
zend_free_op free_op1 ;
zval * val ;
int retval ;
2010-04-20 19:16:39 +08:00
2012-08-22 18:32:03 +08:00
SAVE_OPLINE ( ) ;
val = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
if ( OP1_TYPE = = IS_TMP_VAR & & EXPECTED ( Z_TYPE_P ( val ) = = IS_BOOL ) ) {
retval = Z_LVAL_P ( val ) ;
} else {
retval = i_zend_is_true ( val ) ;
FREE_OP1 ( ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
}
Z_LVAL ( EX_T ( opline - > result . var ) . tmp_var ) = retval ;
Z_TYPE ( EX_T ( opline - > result . var ) . tmp_var ) = IS_BOOL ;
if ( retval ) {
# 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 ( ) ;
}
ZEND_VM_NEXT_OPCODE ( ) ;
}
2011-06-07 05:42:05 +08:00
2012-08-22 18:32:03 +08:00
ZEND_VM_HANDLER ( 70 , ZEND_FREE , TMP | VAR , ANY )
{
USE_OPLINE
2012-01-26 09:28:37 +08:00
2012-08-22 18:32:03 +08:00
SAVE_OPLINE ( ) ;
if ( OP1_TYPE = = IS_TMP_VAR ) {
zendi_zval_dtor ( EX_T ( opline - > op1 . var ) . tmp_var ) ;
} else {
zval_ptr_dtor ( & EX_T ( opline - > op1 . var ) . var . ptr ) ;
}
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2012-01-26 09:28:37 +08:00
2012-08-22 18:32:03 +08:00
ZEND_VM_HANDLER ( 53 , ZEND_INIT_STRING , ANY , ANY )
{
USE_OPLINE
zval * tmp = & EX_T ( opline - > result . var ) . tmp_var ;
2012-01-26 09:28:37 +08:00
2012-08-22 18:32:03 +08:00
SAVE_OPLINE ( ) ;
tmp - > value . str . val = emalloc ( 1 ) ;
tmp - > value . str . val [ 0 ] = 0 ;
tmp - > value . str . len = 0 ;
Z_SET_REFCOUNT_P ( tmp , 1 ) ;
tmp - > type = IS_STRING ;
Z_UNSET_ISREF_P ( tmp ) ;
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE ( ) ;
}
2012-01-26 09:28:37 +08:00
2012-08-22 18:32:03 +08:00
ZEND_VM_HANDLER ( 54 , ZEND_ADD_CHAR , TMP | UNUSED , CONST )
{
USE_OPLINE
zval * str = & EX_T ( opline - > result . var ) . tmp_var ;
2011-06-07 05:42:05 +08:00
2012-08-22 18:32:03 +08:00
SAVE_OPLINE ( ) ;
2012-05-13 13:12:48 +08:00
2012-08-22 18:32:03 +08:00
if ( OP1_TYPE = = IS_UNUSED ) {
/* Initialize for erealloc in add_char_to_string */
Z_STRVAL_P ( str ) = NULL ;
Z_STRLEN_P ( str ) = 0 ;
Z_TYPE_P ( str ) = IS_STRING ;
2011-06-07 05:42:05 +08:00
2012-08-22 18:32:03 +08:00
INIT_PZVAL ( str ) ;
2005-06-16 22:20:00 +08:00
}
2007-11-22 17:02:55 +08:00
2012-08-22 18:32:03 +08:00
add_char_to_string ( str , str , opline - > op2 . zv ) ;
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 55 , ZEND_ADD_STRING , TMP | UNUSED , CONST )
2007-11-22 17:02:55 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2012-08-22 18:32:03 +08:00
zval * str = & EX_T ( opline - > result . var ) . tmp_var ;
2010-04-27 20:23:29 +08:00
2012-08-22 18:32:03 +08:00
SAVE_OPLINE ( ) ;
2010-04-27 20:23:29 +08:00
2012-08-22 18:32:03 +08:00
if ( OP1_TYPE = = IS_UNUSED ) {
/* Initialize for erealloc in add_string_to_string */
Z_STRVAL_P ( str ) = NULL ;
Z_STRLEN_P ( str ) = 0 ;
Z_TYPE_P ( str ) = IS_STRING ;
INIT_PZVAL ( str ) ;
2007-11-22 17:02:55 +08:00
}
2010-04-20 18:57:45 +08:00
add_string_to_string ( str , str , opline - > op2 . zv ) ;
2004-10-23 05:42:14 +08:00
/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
2010-04-20 19:16:39 +08:00
/*CHECK_EXCEPTION();*/
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2008-07-26 23:30:28 +08:00
ZEND_VM_HANDLER ( 56 , ZEND_ADD_VAR , TMP | UNUSED , TMP | VAR | CV )
2008-06-11 21:18:41 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2008-07-26 23:30:28 +08:00
zend_free_op free_op2 ;
2010-04-20 18:57:45 +08:00
zval * str = & EX_T ( opline - > result . var ) . tmp_var ;
2010-04-20 19:16:39 +08:00
zval * var ;
2004-10-23 05:42:14 +08:00
zval var_copy ;
2007-05-18 21:12:05 +08:00
int use_copy = 0 ;
2008-06-11 21:18:41 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
var = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2012-08-13 23:17:18 +08:00
2008-07-26 23:30:28 +08:00
if ( OP1_TYPE = = IS_UNUSED ) {
/* Initialize for erealloc in add_string_to_string */
Z_STRVAL_P ( str ) = NULL ;
Z_STRLEN_P ( str ) = 0 ;
Z_TYPE_P ( str ) = IS_STRING ;
2012-08-13 23:17:18 +08:00
2008-07-26 23:30:28 +08:00
INIT_PZVAL ( str ) ;
2012-08-13 23:17:18 +08:00
}
2007-05-18 21:12:05 +08:00
if ( Z_TYPE_P ( var ) ! = IS_STRING ) {
zend_make_printable_zval ( var , & var_copy , & use_copy ) ;
if ( use_copy ) {
var = & var_copy ;
}
2008-06-11 21:18:41 +08:00
}
2008-07-26 23:30:28 +08:00
add_string_to_string ( str , str , var ) ;
2011-03-16 13:25:02 +08:00
2004-10-23 05:42:14 +08:00
if ( use_copy ) {
zval_dtor ( var ) ;
2011-04-20 20:59:18 +08:00
}
2004-10-23 05:42:14 +08:00
/* original comment, possibly problematic:
* FREE_OP is missing intentionally here - we ' re always working on the same temporary variable
* ( Zeev ) : I don ' t think it ' s problematic , we only use variables
* which aren ' t affected by FREE_OP ( Ts , ) ' s anyway , unless they ' re
* string offsets or overloaded objects
*/
FREE_OP2 ( ) ;
2011-04-20 20:59:18 +08:00
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2011-03-16 13:25:02 +08:00
2004-10-23 05:42:14 +08:00
ZEND_VM_HANDLER ( 109 , ZEND_FETCH_CLASS , ANY , CONST | TMP | VAR | UNUSED | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2008-06-11 21:18:41 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2012-08-14 08:59:40 +08:00
if ( EG ( exception ) ) {
zend_exception_save ( TSRMLS_C ) ;
2010-04-20 19:16:39 +08:00
}
2004-10-23 05:42:14 +08:00
if ( OP2_TYPE = = IS_UNUSED ) {
2010-04-20 18:57:45 +08:00
EX_T ( opline - > result . var ) . class_entry = zend_fetch_class ( NULL , 0 , opline - > extended_value TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
2009-04-08 21:19:34 +08:00
} else {
zend_free_op free_op2 ;
zval * class_name = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2008-06-11 21:18:41 +08:00
2010-04-20 18:57:45 +08:00
if ( OP2_TYPE = = IS_CONST ) {
2010-05-24 22:11:39 +08:00
if ( CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ) {
EX_T ( opline - > result . var ) . class_entry = CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ;
} else {
EX_T ( opline - > result . var ) . class_entry = zend_fetch_class_by_name ( Z_STRVAL_P ( class_name ) , Z_STRLEN_P ( class_name ) , opline - > op2 . literal + 1 , opline - > extended_value TSRMLS_CC ) ;
CACHE_PTR ( opline - > op2 . literal - > cache_slot , EX_T ( opline - > result . var ) . class_entry ) ;
}
2010-04-20 18:57:45 +08:00
} else if ( Z_TYPE_P ( class_name ) = = IS_OBJECT ) {
EX_T ( opline - > result . var ) . class_entry = Z_OBJCE_P ( class_name ) ;
2009-04-08 21:19:34 +08:00
} else if ( Z_TYPE_P ( class_name ) = = IS_STRING ) {
2010-04-20 18:57:45 +08:00
EX_T ( opline - > result . var ) . class_entry = zend_fetch_class ( Z_STRVAL_P ( class_name ) , Z_STRLEN_P ( class_name ) , opline - > extended_value TSRMLS_CC ) ;
2009-04-08 21:19:34 +08:00
} else {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Class name must be a valid object or a string " ) ;
2009-04-08 21:19:34 +08:00
}
2008-06-11 21:18:41 +08:00
2009-04-08 21:19:34 +08:00
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2009-04-08 21:19:34 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
}
2008-06-11 21:18:41 +08:00
2004-10-23 05:42:14 +08:00
ZEND_VM_HANDLER ( 112 , ZEND_INIT_METHOD_CALL , TMP | VAR | UNUSED | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zval * function_name ;
char * function_name_strval ;
int function_name_strlen ;
zend_free_op free_op1 , free_op2 ;
2012-11-30 17:39:23 +08:00
call_slot * call = EX ( call_slots ) + opline - > result . num ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
function_name = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2008-06-11 21:18:41 +08:00
2010-04-20 19:16:39 +08:00
if ( OP2_TYPE ! = IS_CONST & &
UNEXPECTED ( Z_TYPE_P ( function_name ) ! = IS_STRING ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Method name must be a string " ) ;
}
2008-06-11 21:18:41 +08:00
2006-05-12 05:07:39 +08:00
function_name_strval = Z_STRVAL_P ( function_name ) ;
function_name_strlen = Z_STRLEN_P ( function_name ) ;
2008-06-11 21:18:41 +08:00
2012-11-30 17:39:23 +08:00
call - > object = GET_OP1_OBJ_ZVAL_PTR ( BP_VAR_R ) ;
2008-06-11 21:18:41 +08:00
2012-11-30 17:39:23 +08:00
if ( EXPECTED ( call - > object ! = NULL ) & &
EXPECTED ( Z_TYPE_P ( call - > object ) = = IS_OBJECT ) ) {
call - > called_scope = Z_OBJCE_P ( call - > object ) ;
2008-06-11 21:18:41 +08:00
2010-05-24 22:11:39 +08:00
if ( OP2_TYPE ! = IS_CONST | |
2012-11-30 17:39:23 +08:00
( call - > fbc = CACHED_POLYMORPHIC_PTR ( opline - > op2 . literal - > cache_slot , call - > called_scope ) ) = = NULL ) {
zval * object = call - > object ;
2008-06-11 21:18:41 +08:00
2012-11-30 17:39:23 +08:00
if ( UNEXPECTED ( Z_OBJ_HT_P ( call - > object ) - > get_method = = NULL ) ) {
2010-05-24 22:11:39 +08:00
zend_error_noreturn ( E_ERROR , " Object does not support method calls " ) ;
}
2008-06-11 21:18:41 +08:00
2010-05-24 22:11:39 +08:00
/* First, locate the function. */
2012-11-30 17:39:23 +08:00
call - > fbc = Z_OBJ_HT_P ( call - > object ) - > get_method ( & call - > object , function_name_strval , function_name_strlen , ( ( OP2_TYPE = = IS_CONST ) ? ( opline - > op2 . literal + 1 ) : NULL ) TSRMLS_CC ) ;
if ( UNEXPECTED ( call - > fbc = = NULL ) ) {
zend_error_noreturn ( E_ERROR , " Call to undefined method %s::%s() " , Z_OBJ_CLASS_NAME_P ( call - > object ) , function_name_strval ) ;
2008-06-11 21:18:41 +08:00
}
2010-05-24 22:11:39 +08:00
if ( OP2_TYPE = = IS_CONST & &
2012-11-30 17:39:23 +08:00
EXPECTED ( call - > fbc - > type < = ZEND_USER_FUNCTION ) & &
EXPECTED ( ( call - > fbc - > common . fn_flags & ( ZEND_ACC_CALL_VIA_HANDLER | ZEND_ACC_NEVER_CACHE ) ) = = 0 ) & &
EXPECTED ( call - > object = = object ) ) {
CACHE_POLYMORPHIC_PTR ( opline - > op2 . literal - > cache_slot , call - > called_scope , call - > fbc ) ;
2010-05-24 22:11:39 +08:00
}
2004-10-23 05:42:14 +08:00
}
} else {
zend_error_noreturn ( E_ERROR , " Call to a member function %s() on a non-object " , function_name_strval ) ;
}
2008-06-11 21:18:41 +08:00
2012-11-30 17:39:23 +08:00
if ( ( call - > fbc - > common . fn_flags & ZEND_ACC_STATIC ) ! = 0 ) {
call - > object = NULL ;
2011-03-16 13:25:02 +08:00
} else {
2012-11-30 17:39:23 +08:00
if ( ! PZVAL_IS_REF ( call - > object ) ) {
Z_ADDREF_P ( call - > object ) ; /* For $this pointer */
2004-10-23 05:42:14 +08:00
} else {
zval * this_ptr ;
ALLOC_ZVAL ( this_ptr ) ;
2012-11-30 17:39:23 +08:00
INIT_PZVAL_COPY ( this_ptr , call - > object ) ;
2004-10-23 05:42:14 +08:00
zval_copy_ctor ( this_ptr ) ;
2012-11-30 17:39:23 +08:00
call - > object = this_ptr ;
2008-06-11 21:18:41 +08:00
}
}
2012-11-30 17:39:23 +08:00
call - > is_ctor_call = 0 ;
EX ( call ) = call ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
FREE_OP1_IF_VAR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
2008-06-11 21:18:41 +08:00
}
2004-10-23 05:42:14 +08:00
2007-09-29 03:52:53 +08:00
ZEND_VM_HANDLER ( 113 , ZEND_INIT_STATIC_METHOD_CALL , CONST | VAR , CONST | TMP | VAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zval * function_name ;
zend_class_entry * ce ;
2012-11-30 17:39:23 +08:00
call_slot * call = EX ( call_slots ) + opline - > result . num ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2007-10-03 14:49:15 +08:00
2009-03-10 18:01:44 +08:00
if ( OP1_TYPE = = IS_CONST ) {
2007-10-03 14:49:15 +08:00
/* no function found. try a static method in class */
2010-05-24 22:11:39 +08:00
if ( CACHED_PTR ( opline - > op1 . literal - > cache_slot ) ) {
ce = CACHED_PTR ( opline - > op1 . literal - > cache_slot ) ;
2007-09-29 15:28:34 +08:00
} else {
2010-05-24 22:11:39 +08:00
ce = zend_fetch_class_by_name ( Z_STRVAL_P ( opline - > op1 . zv ) , Z_STRLEN_P ( opline - > op1 . zv ) , opline - > op1 . literal + 1 , opline - > extended_value TSRMLS_CC ) ;
if ( UNEXPECTED ( ce = = NULL ) ) {
2012-02-25 21:56:59 +08:00
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2010-05-24 22:11:39 +08:00
}
CACHE_PTR ( opline - > op1 . literal - > cache_slot , ce ) ;
2007-09-29 15:28:34 +08:00
}
2012-11-30 17:39:23 +08:00
call - > called_scope = ce ;
2007-09-29 03:52:53 +08:00
} else {
2010-04-20 18:57:45 +08:00
ce = EX_T ( opline - > op1 . var ) . class_entry ;
2004-10-23 05:42:14 +08:00
2010-04-20 18:57:45 +08:00
if ( opline - > extended_value = = ZEND_FETCH_CLASS_PARENT | | opline - > extended_value = = ZEND_FETCH_CLASS_SELF ) {
2012-11-30 17:39:23 +08:00
call - > called_scope = EG ( called_scope ) ;
2008-07-24 17:42:18 +08:00
} else {
2012-11-30 17:39:23 +08:00
call - > called_scope = ce ;
2008-07-24 17:42:18 +08:00
}
2004-10-23 05:42:14 +08:00
}
2010-05-24 22:11:39 +08:00
if ( OP1_TYPE = = IS_CONST & &
OP2_TYPE = = IS_CONST & &
CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ) {
2012-11-30 17:39:23 +08:00
call - > fbc = CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ;
2010-05-24 22:11:39 +08:00
} else if ( OP1_TYPE ! = IS_CONST & &
OP2_TYPE = = IS_CONST & &
2012-11-30 17:39:23 +08:00
( call - > fbc = CACHED_POLYMORPHIC_PTR ( opline - > op2 . literal - > cache_slot , ce ) ) ) {
2010-05-24 22:11:39 +08:00
/* do nothing */
} else if ( OP2_TYPE ! = IS_UNUSED ) {
2008-10-06 08:40:02 +08:00
char * function_name_strval = NULL ;
2008-06-04 02:11:12 +08:00
int function_name_strlen = 0 ;
2004-10-23 05:42:14 +08:00
zend_free_op free_op2 ;
2007-09-29 15:28:34 +08:00
2008-01-24 01:55:55 +08:00
if ( OP2_TYPE = = IS_CONST ) {
2010-04-20 18:57:45 +08:00
function_name_strval = Z_STRVAL_P ( opline - > op2 . zv ) ;
function_name_strlen = Z_STRLEN_P ( opline - > op2 . zv ) ;
2004-10-23 05:42:14 +08:00
} else {
function_name = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( function_name ) ! = IS_STRING ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Function name must be a string " ) ;
2008-06-04 02:11:12 +08:00
} else {
function_name_strval = Z_STRVAL_P ( function_name ) ;
function_name_strlen = Z_STRLEN_P ( function_name ) ;
}
2004-10-23 05:42:14 +08:00
}
2010-04-20 19:16:39 +08:00
2008-10-06 08:40:02 +08:00
if ( function_name_strval ) {
2008-06-04 02:11:12 +08:00
if ( ce - > get_static_method ) {
2012-11-30 17:39:23 +08:00
call - > fbc = ce - > get_static_method ( ce , function_name_strval , function_name_strlen TSRMLS_CC ) ;
2008-06-04 02:11:12 +08:00
} else {
2012-11-30 17:39:23 +08:00
call - > fbc = zend_std_get_static_method ( ce , function_name_strval , function_name_strlen , ( ( OP2_TYPE = = IS_CONST ) ? ( opline - > op2 . literal + 1 ) : NULL ) TSRMLS_CC ) ;
2008-06-04 02:11:12 +08:00
}
2012-11-30 17:39:23 +08:00
if ( UNEXPECTED ( call - > fbc = = NULL ) ) {
2009-03-19 02:49:27 +08:00
zend_error_noreturn ( E_ERROR , " Call to undefined method %s::%s() " , ce - > name , function_name_strval ) ;
2008-07-26 21:14:04 +08:00
}
2012-01-30 18:51:02 +08:00
if ( OP2_TYPE = = IS_CONST & &
2012-11-30 17:39:23 +08:00
EXPECTED ( call - > fbc - > type < = ZEND_USER_FUNCTION ) & &
EXPECTED ( ( call - > fbc - > common . fn_flags & ( ZEND_ACC_CALL_VIA_HANDLER | ZEND_ACC_NEVER_CACHE ) ) = = 0 ) ) {
2010-05-24 22:11:39 +08:00
if ( OP1_TYPE = = IS_CONST ) {
2012-11-30 17:39:23 +08:00
CACHE_PTR ( opline - > op2 . literal - > cache_slot , call - > fbc ) ;
2010-05-24 22:11:39 +08:00
} else {
2012-11-30 17:39:23 +08:00
CACHE_POLYMORPHIC_PTR ( opline - > op2 . literal - > cache_slot , ce , call - > fbc ) ;
2010-05-24 22:11:39 +08:00
}
}
2007-09-29 17:34:24 +08:00
}
2008-01-24 01:55:55 +08:00
if ( OP2_TYPE ! = IS_CONST ) {
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
}
} else {
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( ce - > constructor = = NULL ) ) {
2009-06-07 23:46:54 +08:00
zend_error_noreturn ( E_ERROR , " Cannot call constructor " ) ;
2004-10-23 05:42:14 +08:00
}
2007-02-25 05:30:48 +08:00
if ( EG ( This ) & & Z_OBJCE_P ( EG ( This ) ) ! = ce - > constructor - > common . scope & & ( ce - > constructor - > common . fn_flags & ZEND_ACC_PRIVATE ) ) {
2010-04-20 19:16:39 +08:00
zend_error_noreturn ( E_ERROR , " Cannot call private %s::__construct() " , ce - > name ) ;
2006-08-08 07:24:33 +08:00
}
2012-11-30 17:39:23 +08:00
call - > fbc = ce - > constructor ;
2004-10-23 05:42:14 +08:00
}
2012-11-30 17:39:23 +08:00
if ( call - > fbc - > common . fn_flags & ZEND_ACC_STATIC ) {
call - > object = NULL ;
2004-10-23 05:42:14 +08:00
} else {
2008-02-11 23:46:10 +08:00
if ( EG ( This ) & &
2006-03-15 19:12:45 +08:00
Z_OBJ_HT_P ( EG ( This ) ) - > get_class_entry & &
2006-05-12 05:07:39 +08:00
! instanceof_function ( Z_OBJCE_P ( EG ( This ) ) , ce TSRMLS_CC ) ) {
2006-03-15 19:12:45 +08:00
/* We are calling method of the other (incompatible) class,
but passing $ this . This is done for compatibility with php - 4. */
2012-11-30 17:39:23 +08:00
if ( call - > fbc - > common . fn_flags & ZEND_ACC_ALLOW_STATIC ) {
zend_error ( E_STRICT , " Non-static method %s::%s() should not be called statically, assuming $this from incompatible context " , call - > fbc - > common . scope - > name , call - > fbc - > common . function_name ) ;
2008-02-02 21:56:59 +08:00
} else {
2008-02-02 23:48:04 +08:00
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
2012-11-30 17:39:23 +08:00
zend_error_noreturn ( E_ERROR , " Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context " , call - > fbc - > common . scope - > name , call - > fbc - > common . function_name ) ;
2004-10-23 05:42:14 +08:00
}
}
2012-11-30 17:39:23 +08:00
if ( ( call - > object = EG ( This ) ) ) {
Z_ADDREF_P ( call - > object ) ;
call - > called_scope = Z_OBJCE_P ( call - > object ) ;
2004-10-23 05:42:14 +08:00
}
}
2012-11-30 17:39:23 +08:00
call - > is_ctor_call = 0 ;
EX ( call ) = call ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 59 , ZEND_INIT_FCALL_BY_NAME , ANY , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zval * function_name ;
2012-11-30 17:39:23 +08:00
call_slot * call = EX ( call_slots ) + opline - > result . num ;
2004-10-23 05:42:14 +08:00
if ( OP2_TYPE = = IS_CONST ) {
2010-04-27 20:09:13 +08:00
function_name = ( zval * ) ( opline - > op2 . literal + 1 ) ;
2010-05-24 22:11:39 +08:00
if ( CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ) {
2012-11-30 17:39:23 +08:00
call - > fbc = CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ;
} else if ( UNEXPECTED ( zend_hash_quick_find ( EG ( function_table ) , Z_STRVAL_P ( function_name ) , Z_STRLEN_P ( function_name ) + 1 , Z_HASH_P ( function_name ) , ( void * * ) & call - > fbc ) = = FAILURE ) ) {
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
zend_error_noreturn ( E_ERROR , " Call to undefined function %s() " , Z_STRVAL_P ( opline - > op2 . zv ) ) ;
2004-10-23 05:42:14 +08:00
} else {
2012-11-30 17:39:23 +08:00
CACHE_PTR ( opline - > op2 . literal - > cache_slot , call - > fbc ) ;
2004-10-23 05:42:14 +08:00
}
2012-11-30 17:39:23 +08:00
call - > object = NULL ;
2012-12-14 16:10:29 +08:00
call - > called_scope = NULL ;
2012-11-30 17:39:23 +08:00
call - > is_ctor_call = 0 ;
EX ( call ) = call ;
2010-04-20 19:16:39 +08:00
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE ( ) ;
2004-10-23 05:42:14 +08:00
} else {
2010-04-20 19:16:39 +08:00
char * function_name_strval , * lcname ;
int function_name_strlen ;
zend_free_op free_op2 ;
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
function_name = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2010-04-20 19:16:39 +08:00
if ( EXPECTED ( Z_TYPE_P ( function_name ) = = IS_STRING ) ) {
function_name_strval = Z_STRVAL_P ( function_name ) ;
function_name_strlen = Z_STRLEN_P ( function_name ) ;
if ( function_name_strval [ 0 ] = = ' \\ ' ) {
function_name_strlen - = 1 ;
lcname = zend_str_tolower_dup ( function_name_strval + 1 , function_name_strlen ) ;
} else {
lcname = zend_str_tolower_dup ( function_name_strval , function_name_strlen ) ;
2012-07-20 06:49:50 +08:00
}
2012-11-30 17:39:23 +08:00
if ( UNEXPECTED ( zend_hash_find ( EG ( function_table ) , lcname , function_name_strlen + 1 , ( void * * ) & call - > fbc ) = = FAILURE ) ) {
2010-04-20 19:16:39 +08:00
zend_error_noreturn ( E_ERROR , " Call to undefined function %s() " , function_name_strval ) ;
}
efree ( lcname ) ;
FREE_OP2 ( ) ;
2012-11-30 17:39:23 +08:00
call - > object = NULL ;
2012-12-14 16:10:29 +08:00
call - > called_scope = NULL ;
2012-11-30 17:39:23 +08:00
call - > is_ctor_call = 0 ;
EX ( call ) = call ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2011-04-20 20:59:18 +08:00
} else if ( OP2_TYPE ! = IS_CONST & & OP2_TYPE ! = IS_TMP_VAR & &
2010-04-20 19:16:39 +08:00
EXPECTED ( Z_TYPE_P ( function_name ) = = IS_OBJECT ) & &
2008-08-15 05:36:56 +08:00
Z_OBJ_HANDLER_P ( function_name , get_closure ) & &
2012-11-30 17:39:23 +08:00
Z_OBJ_HANDLER_P ( function_name , get_closure ) ( function_name , & call - > called_scope , & call - > fbc , & call - > object TSRMLS_CC ) = = SUCCESS ) {
if ( call - > object ) {
Z_ADDREF_P ( call - > object ) ;
2008-07-14 17:49:03 +08:00
}
2011-04-20 20:59:18 +08:00
if ( OP2_TYPE = = IS_VAR & & OP2_FREE & &
2012-11-30 17:39:23 +08:00
call - > fbc - > common . fn_flags & ZEND_ACC_CLOSURE ) {
2011-04-20 20:59:18 +08:00
/* Delay closure destruction until its invocation */
2012-11-30 17:39:23 +08:00
call - > fbc - > common . prototype = ( zend_function * ) function_name ;
2012-08-22 18:32:03 +08:00
} else {
FREE_OP2 ( ) ;
2004-10-23 05:42:14 +08:00
}
2012-11-30 17:39:23 +08:00
call - > is_ctor_call = 0 ;
EX ( call ) = call ;
2012-08-22 18:32:03 +08:00
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( OP2_TYPE ! = IS_CONST & &
EXPECTED ( Z_TYPE_P ( function_name ) = = IS_ARRAY ) & &
zend_hash_num_elements ( Z_ARRVAL_P ( function_name ) ) = = 2 ) {
zend_class_entry * ce ;
zval * * method = NULL ;
zval * * obj = NULL ;
2008-04-21 18:14:20 +08:00
2012-08-22 18:32:03 +08:00
zend_hash_index_find ( Z_ARRVAL_P ( function_name ) , 0 , ( void * * ) & obj ) ;
zend_hash_index_find ( Z_ARRVAL_P ( function_name ) , 1 , ( void * * ) & method ) ;
2004-10-23 05:42:14 +08:00
2012-09-28 00:46:27 +08:00
if ( ! obj | | ! method ) {
zend_error_noreturn ( E_ERROR , " Array callback has to contain indices 0 and 1 " ) ;
2010-04-20 19:16:39 +08:00
}
2008-04-21 18:14:20 +08:00
2012-08-22 18:32:03 +08:00
if ( Z_TYPE_PP ( obj ) ! = IS_STRING & & Z_TYPE_PP ( obj ) ! = IS_OBJECT ) {
zend_error_noreturn ( E_ERROR , " First array member is not a valid class name or object " ) ;
2010-04-20 19:16:39 +08:00
}
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
if ( Z_TYPE_PP ( method ) ! = IS_STRING ) {
zend_error_noreturn ( E_ERROR , " Second array member is not a valid method " ) ;
2008-04-29 16:15:20 +08:00
}
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
if ( Z_TYPE_PP ( obj ) = = IS_STRING ) {
ce = zend_fetch_class_by_name ( Z_STRVAL_PP ( obj ) , Z_STRLEN_PP ( obj ) , NULL , 0 TSRMLS_CC ) ;
if ( UNEXPECTED ( ce = = NULL ) ) {
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2012-11-30 17:39:23 +08:00
call - > called_scope = ce ;
call - > object = NULL ;
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
if ( ce - > get_static_method ) {
2012-11-30 17:39:23 +08:00
call - > fbc = ce - > get_static_method ( ce , Z_STRVAL_PP ( method ) , Z_STRLEN_PP ( method ) TSRMLS_CC ) ;
2012-08-22 18:32:03 +08:00
} else {
2012-11-30 17:39:23 +08:00
call - > fbc = zend_std_get_static_method ( ce , Z_STRVAL_PP ( method ) , Z_STRLEN_PP ( method ) , NULL TSRMLS_CC ) ;
2012-08-22 18:32:03 +08:00
}
} else {
2012-11-30 17:39:23 +08:00
call - > object = * obj ;
ce = call - > called_scope = Z_OBJCE_PP ( obj ) ;
2007-11-06 22:56:14 +08:00
2012-11-30 17:39:23 +08:00
call - > fbc = Z_OBJ_HT_P ( call - > object ) - > get_method ( & call - > object , Z_STRVAL_PP ( method ) , Z_STRLEN_PP ( method ) , NULL TSRMLS_CC ) ;
if ( UNEXPECTED ( call - > fbc = = NULL ) ) {
zend_error_noreturn ( E_ERROR , " Call to undefined method %s::%s() " , Z_OBJ_CLASS_NAME_P ( call - > object ) , Z_STRVAL_PP ( method ) ) ;
2008-04-21 18:14:20 +08:00
}
2012-08-22 18:32:03 +08:00
2012-11-30 17:39:23 +08:00
if ( ( call - > fbc - > common . fn_flags & ZEND_ACC_STATIC ) ! = 0 ) {
call - > object = NULL ;
2012-08-22 18:32:03 +08:00
} else {
2012-11-30 17:39:23 +08:00
if ( ! PZVAL_IS_REF ( call - > object ) ) {
Z_ADDREF_P ( call - > object ) ; /* For $this pointer */
2012-08-22 18:32:03 +08:00
} else {
zval * this_ptr ;
ALLOC_ZVAL ( this_ptr ) ;
2012-11-30 17:39:23 +08:00
INIT_PZVAL_COPY ( this_ptr , call - > object ) ;
2012-08-22 18:32:03 +08:00
zval_copy_ctor ( this_ptr ) ;
2012-11-30 17:39:23 +08:00
call - > object = this_ptr ;
2012-08-22 18:32:03 +08:00
}
2008-04-21 18:14:20 +08:00
}
2005-05-04 16:45:46 +08:00
}
2012-08-22 18:32:03 +08:00
2012-11-30 17:39:23 +08:00
if ( UNEXPECTED ( call - > fbc = = NULL ) ) {
2012-08-22 18:32:03 +08:00
zend_error_noreturn ( E_ERROR , " Call to undefined method %s::%s() " , ce - > name , Z_STRVAL_PP ( method ) ) ;
}
2012-11-30 17:39:23 +08:00
call - > is_ctor_call = 0 ;
EX ( call ) = call ;
2012-08-22 18:32:03 +08:00
FREE_OP2 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else {
zend_error_noreturn ( E_ERROR , " Function name must be a string " ) ;
2012-12-14 17:21:43 +08:00
ZEND_VM_NEXT_OPCODE ( ) ; /* Never reached */
2004-10-23 05:42:14 +08:00
}
}
2012-08-22 18:32:03 +08:00
}
2004-10-23 05:42:14 +08:00
2008-04-21 18:14:20 +08:00
2012-08-22 18:32:03 +08:00
ZEND_VM_HANDLER ( 69 , ZEND_INIT_NS_FCALL_BY_NAME , ANY , CONST )
{
USE_OPLINE
zend_literal * func_name ;
2012-11-30 17:39:23 +08:00
call_slot * call = EX ( call_slots ) + opline - > result . num ;
2012-08-22 18:32:03 +08:00
func_name = opline - > op2 . literal + 1 ;
if ( CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ) {
2012-11-30 17:39:23 +08:00
call - > fbc = CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ;
} else if ( zend_hash_quick_find ( EG ( function_table ) , Z_STRVAL ( func_name - > constant ) , Z_STRLEN ( func_name - > constant ) + 1 , func_name - > hash_value , ( void * * ) & call - > fbc ) = = FAILURE ) {
2012-08-22 18:32:03 +08:00
func_name + + ;
2012-11-30 17:39:23 +08:00
if ( UNEXPECTED ( zend_hash_quick_find ( EG ( function_table ) , Z_STRVAL ( func_name - > constant ) , Z_STRLEN ( func_name - > constant ) + 1 , func_name - > hash_value , ( void * * ) & call - > fbc ) = = FAILURE ) ) {
2012-08-22 18:32:03 +08:00
SAVE_OPLINE ( ) ;
zend_error_noreturn ( E_ERROR , " Call to undefined function %s() " , Z_STRVAL_P ( opline - > op2 . zv ) ) ;
} else {
2012-11-30 17:39:23 +08:00
CACHE_PTR ( opline - > op2 . literal - > cache_slot , call - > fbc ) ;
2004-10-23 05:42:14 +08:00
}
2012-08-22 18:32:03 +08:00
} else {
2012-11-30 17:39:23 +08:00
CACHE_PTR ( opline - > op2 . literal - > cache_slot , call - > fbc ) ;
2004-10-23 05:42:14 +08:00
}
2012-11-30 17:39:23 +08:00
call - > object = NULL ;
2012-12-14 16:10:29 +08:00
call - > called_scope = NULL ;
2012-11-30 17:39:23 +08:00
call - > is_ctor_call = 0 ;
EX ( call ) = call ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 61 , ZEND_DO_FCALL_BY_NAME , ANY , ANY )
{
2012-11-30 17:39:23 +08:00
EX ( function_state ) . function = EX ( call ) - > fbc ;
2004-10-23 05:42:14 +08:00
ZEND_VM_DISPATCH_TO_HELPER ( zend_do_fcall_common_helper ) ;
}
ZEND_VM_HANDLER ( 60 , ZEND_DO_FCALL , CONST , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
zval * fname = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2012-11-30 17:39:23 +08:00
call_slot * call = EX ( call_slots ) + opline - > op2 . num ;
2004-10-23 05:42:14 +08:00
2010-05-24 22:11:39 +08:00
if ( CACHED_PTR ( opline - > op1 . literal - > cache_slot ) ) {
EX ( function_state ) . function = CACHED_PTR ( opline - > op1 . literal - > cache_slot ) ;
} else if ( UNEXPECTED ( zend_hash_quick_find ( EG ( function_table ) , Z_STRVAL_P ( fname ) , Z_STRLEN_P ( fname ) + 1 , Z_HASH_P ( fname ) , ( void * * ) & EX ( function_state ) . function ) = = FAILURE ) ) {
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2006-08-03 18:57:41 +08:00
zend_error_noreturn ( E_ERROR , " Call to undefined function %s() " , fname - > value . str . val ) ;
2010-05-24 22:11:39 +08:00
} else {
CACHE_PTR ( opline - > op1 . literal - > cache_slot , EX ( function_state ) . function ) ;
2004-10-23 05:42:14 +08:00
}
2012-11-30 17:39:23 +08:00
call - > fbc = EX ( function_state ) . function ;
call - > object = NULL ;
2012-12-14 16:10:29 +08:00
call - > called_scope = NULL ;
2012-11-30 17:39:23 +08:00
call - > is_ctor_call = 0 ;
EX ( call ) = call ;
2004-10-23 05:42:14 +08:00
FREE_OP1 ( ) ;
ZEND_VM_DISPATCH_TO_HELPER ( zend_do_fcall_common_helper ) ;
}
ZEND_VM_HANDLER ( 62 , ZEND_RETURN , CONST | TMP | VAR | CV , ANY )
2010-04-22 19:56:45 +08:00
{
USE_OPLINE
zval * retval_ptr ;
zend_free_op free_op1 ;
SAVE_OPLINE ( ) ;
retval_ptr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
if ( ! EG ( return_value_ptr_ptr ) ) {
if ( OP1_TYPE = = IS_TMP_VAR ) {
FREE_OP1 ( ) ;
}
} else if ( ! IS_OP1_TMP_FREE ( ) ) { /* Not a temp var */
2012-08-14 08:59:40 +08:00
if ( * EG ( return_value_ptr_ptr ) ) {
zval_ptr_dtor ( EG ( return_value_ptr_ptr ) ) ;
}
2010-04-22 19:56:45 +08:00
if ( OP1_TYPE = = IS_CONST | |
( PZVAL_IS_REF ( retval_ptr ) & & Z_REFCOUNT_P ( retval_ptr ) > 0 ) ) {
zval * ret ;
ALLOC_ZVAL ( ret ) ;
INIT_PZVAL_COPY ( ret , retval_ptr ) ;
zval_copy_ctor ( ret ) ;
* EG ( return_value_ptr_ptr ) = ret ;
2010-06-15 16:22:51 +08:00
} else if ( ( OP1_TYPE = = IS_CV | | OP1_TYPE = = IS_VAR ) & &
retval_ptr = = & EG ( uninitialized_zval ) ) {
zval * ret ;
ALLOC_INIT_ZVAL ( ret ) ;
* EG ( return_value_ptr_ptr ) = ret ;
2010-04-22 19:56:45 +08:00
} else {
* EG ( return_value_ptr_ptr ) = retval_ptr ;
Z_ADDREF_P ( retval_ptr ) ;
}
} else {
zval * ret ;
2012-08-14 08:59:40 +08:00
if ( * EG ( return_value_ptr_ptr ) ) {
zval_ptr_dtor ( EG ( return_value_ptr_ptr ) ) ;
}
2012-08-13 21:48:39 +08:00
2010-04-22 19:56:45 +08:00
ALLOC_ZVAL ( ret ) ;
INIT_PZVAL_COPY ( ret , retval_ptr ) ;
* EG ( return_value_ptr_ptr ) = ret ;
}
FREE_OP1_IF_VAR ( ) ;
2012-11-22 19:17:05 +08:00
ZEND_VM_DISPATCH_TO_HELPER ( zend_leave_helper ) ;
2010-04-22 19:56:45 +08:00
}
ZEND_VM_HANDLER ( 111 , ZEND_RETURN_BY_REF , CONST | TMP | VAR | CV , ANY )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zval * retval_ptr ;
zval * * retval_ptr_ptr ;
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
2010-04-22 19:56:45 +08:00
do {
2012-08-14 08:59:40 +08:00
if ( EG ( return_value_ptr_ptr ) & & * EG ( return_value_ptr_ptr ) ) {
zval_ptr_dtor ( EG ( return_value_ptr_ptr ) ) ;
}
2012-08-13 21:48:39 +08:00
2004-10-23 05:42:14 +08:00
if ( OP1_TYPE = = IS_CONST | | OP1_TYPE = = IS_TMP_VAR ) {
/* Not supposed to happen, but we'll allow it */
2005-07-12 02:44:37 +08:00
zend_error ( E_NOTICE , " Only variable references should be returned by reference " ) ;
2010-04-22 19:56:45 +08:00
retval_ptr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
if ( ! EG ( return_value_ptr_ptr ) ) {
if ( OP1_TYPE = = IS_TMP_VAR ) {
FREE_OP1 ( ) ;
}
} else if ( ! IS_OP1_TMP_FREE ( ) ) { /* Not a temp var */
zval * ret ;
ALLOC_ZVAL ( ret ) ;
INIT_PZVAL_COPY ( ret , retval_ptr ) ;
zval_copy_ctor ( ret ) ;
* EG ( return_value_ptr_ptr ) = ret ;
} else {
zval * ret ;
ALLOC_ZVAL ( ret ) ;
INIT_PZVAL_COPY ( ret , retval_ptr ) ;
* EG ( return_value_ptr_ptr ) = ret ;
}
break ;
2004-10-23 05:42:14 +08:00
}
retval_ptr_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( retval_ptr_ptr = = NULL ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Cannot return string offsets by reference " ) ;
}
2007-10-07 13:22:07 +08:00
if ( OP1_TYPE = = IS_VAR & & ! Z_ISREF_PP ( retval_ptr_ptr ) ) {
2005-07-18 15:13:34 +08:00
if ( opline - > extended_value = = ZEND_RETURNS_FUNCTION & &
2010-04-20 18:57:45 +08:00
EX_T ( opline - > op1 . var ) . var . fcall_returned_reference ) {
} else if ( EX_T ( opline - > op1 . var ) . var . ptr_ptr = = & EX_T ( opline - > op1 . var ) . var . ptr ) {
2005-07-12 02:44:37 +08:00
zend_error ( E_NOTICE , " Only variable references should be returned by reference " ) ;
2010-04-22 19:56:45 +08:00
if ( EG ( return_value_ptr_ptr ) ) {
retval_ptr = * retval_ptr_ptr ;
* EG ( return_value_ptr_ptr ) = retval_ptr ;
Z_ADDREF_P ( retval_ptr ) ;
}
break ;
2004-10-23 05:42:14 +08:00
}
}
2008-04-11 17:43:28 +08:00
if ( EG ( return_value_ptr_ptr ) ) {
SEPARATE_ZVAL_TO_MAKE_IS_REF ( retval_ptr_ptr ) ;
Z_ADDREF_PP ( retval_ptr_ptr ) ;
2004-10-23 05:42:14 +08:00
2010-04-22 19:56:45 +08:00
* EG ( return_value_ptr_ptr ) = * retval_ptr_ptr ;
2008-04-11 17:43:28 +08:00
}
2010-04-22 19:56:45 +08:00
} while ( 0 ) ;
2004-10-23 05:42:14 +08:00
2010-04-22 19:56:45 +08:00
FREE_OP1_IF_VAR ( ) ;
2012-11-22 19:17:05 +08:00
ZEND_VM_DISPATCH_TO_HELPER ( zend_leave_helper ) ;
2004-10-23 05:42:14 +08:00
}
2012-08-26 01:03:23 +08:00
ZEND_VM_HANDLER ( 161 , ZEND_GENERATOR_RETURN , ANY , ANY )
2012-08-24 19:51:39 +08:00
{
2012-12-11 21:25:32 +08:00
/* 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 ( ) ;
2012-08-24 19:51:39 +08:00
}
2005-06-16 22:20:00 +08:00
ZEND_VM_HANDLER ( 108 , ZEND_THROW , CONST | TMP | VAR | CV , ANY )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zval * value ;
zval * exception ;
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
value = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_CONST | | UNEXPECTED ( Z_TYPE_P ( value ) ! = IS_OBJECT ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Can only throw objects " ) ;
}
2008-08-14 18:24:52 +08:00
zend_exception_save ( TSRMLS_C ) ;
2004-10-23 05:42:14 +08:00
/* Not sure if a complete copy is what we want here */
ALLOC_ZVAL ( exception ) ;
INIT_PZVAL_COPY ( exception , value ) ;
if ( ! IS_OP1_TMP_FREE ( ) ) {
zval_copy_ctor ( exception ) ;
}
zend_throw_exception_object ( exception TSRMLS_CC ) ;
2008-08-14 18:24:52 +08:00
zend_exception_restore ( TSRMLS_C ) ;
2004-10-23 05:42:14 +08:00
FREE_OP1_IF_VAR ( ) ;
2010-04-20 19:16:39 +08:00
HANDLE_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
2010-04-20 19:16:39 +08:00
ZEND_VM_HANDLER ( 107 , ZEND_CATCH , CONST , CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
zend_class_entry * ce , * catch_ce ;
2010-05-24 22:46:31 +08:00
zval * exception ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
/* Check whether an exception has been thrown, if not, jump over code */
2008-08-14 18:24:52 +08:00
zend_exception_restore ( TSRMLS_C ) ;
2004-10-23 05:42:14 +08:00
if ( EG ( exception ) = = NULL ) {
ZEND_VM_SET_OPCODE ( & EX ( op_array ) - > opcodes [ opline - > extended_value ] ) ;
ZEND_VM_CONTINUE ( ) ; /* CHECK_ME */
}
2010-05-24 22:11:39 +08:00
if ( CACHED_PTR ( opline - > op1 . literal - > cache_slot ) ) {
catch_ce = CACHED_PTR ( opline - > op1 . literal - > cache_slot ) ;
} else {
catch_ce = zend_fetch_class_by_name ( Z_STRVAL_P ( opline - > op1 . zv ) , Z_STRLEN_P ( opline - > op1 . zv ) , opline - > op1 . literal + 1 , ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC ) ;
2012-05-13 13:12:48 +08:00
2010-05-24 22:11:39 +08:00
CACHE_PTR ( opline - > op1 . literal - > cache_slot , catch_ce ) ;
}
2004-10-23 05:42:14 +08:00
ce = Z_OBJCE_P ( EG ( exception ) ) ;
2010-04-24 21:32:30 +08:00
# ifdef HAVE_DTRACE
if ( DTRACE_EXCEPTION_CAUGHT_ENABLED ( ) ) {
DTRACE_EXCEPTION_CAUGHT ( ce - > name ) ;
}
# endif /* HAVE_DTRACE */
2010-04-20 19:16:39 +08:00
if ( ce ! = catch_ce ) {
if ( ! instanceof_function ( ce , catch_ce TSRMLS_CC ) ) {
2010-04-20 18:57:45 +08:00
if ( opline - > result . num ) {
2004-10-23 05:42:14 +08:00
zend_throw_exception_internal ( NULL TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
HANDLE_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
ZEND_VM_SET_OPCODE ( & EX ( op_array ) - > opcodes [ opline - > extended_value ] ) ;
ZEND_VM_CONTINUE ( ) ; /* CHECK_ME */
}
}
2010-05-24 22:46:31 +08:00
exception = EG ( exception ) ;
2008-04-29 16:15:20 +08:00
if ( ! EG ( active_symbol_table ) ) {
2010-04-20 19:16:39 +08:00
if ( EX_CV ( opline - > op2 . var ) ) {
zval_ptr_dtor ( EX_CV ( opline - > op2 . var ) ) ;
2008-04-29 16:15:20 +08:00
}
2012-12-04 14:14:39 +08:00
EX_CV ( opline - > op2 . var ) = ( zval * * ) EX_CV_NUM ( execute_data , EX ( op_array ) - > last_var + opline - > op2 . var ) ;
2010-04-20 19:16:39 +08:00
* EX_CV ( opline - > op2 . var ) = EG ( exception ) ;
2008-04-29 16:15:20 +08:00
} else {
2010-04-20 18:57:45 +08:00
zend_compiled_variable * cv = & CV_DEF_OF ( opline - > op2 . var ) ;
2008-04-29 16:15:20 +08:00
zend_hash_quick_update ( EG ( active_symbol_table ) , cv - > name , cv - > name_len + 1 , cv - > hash_value ,
2010-04-20 19:16:39 +08:00
& EG ( exception ) , sizeof ( zval * ) , ( void * * ) & EX_CV ( opline - > op2 . var ) ) ;
2008-04-29 16:15:20 +08:00
}
2010-05-24 22:46:31 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = exception ) ) {
2010-12-10 00:38:37 +08:00
Z_ADDREF_P ( EG ( exception ) ) ;
2010-05-24 22:46:31 +08:00
HANDLE_EXCEPTION ( ) ;
} else {
EG ( exception ) = NULL ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
}
2010-06-22 22:15:08 +08:00
ZEND_VM_HANDLER ( 65 , ZEND_SEND_VAL , CONST | TMP , ANY )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
if ( opline - > extended_value = = ZEND_DO_FCALL_BY_NAME
2012-11-30 17:39:23 +08:00
& & ARG_MUST_BE_SENT_BY_REF ( EX ( call ) - > fbc , opline - > op2 . opline_num ) ) {
2010-04-20 18:57:45 +08:00
zend_error_noreturn ( E_ERROR , " Cannot pass parameter %d by reference " , opline - > op2 . opline_num ) ;
2004-10-23 05:42:14 +08:00
}
{
zval * valptr ;
zval * value ;
zend_free_op free_op1 ;
value = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
ALLOC_ZVAL ( valptr ) ;
INIT_PZVAL_COPY ( valptr , value ) ;
if ( ! IS_OP1_TMP_FREE ( ) ) {
zval_copy_ctor ( valptr ) ;
}
2008-01-24 17:41:39 +08:00
zend_vm_stack_push ( valptr TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
FREE_OP1_IF_VAR ( ) ;
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HELPER ( zend_send_by_var_helper , VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zval * varptr ;
zend_free_op free_op1 ;
varptr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
if ( varptr = = & EG ( uninitialized_zval ) ) {
ALLOC_ZVAL ( varptr ) ;
INIT_ZVAL ( * varptr ) ;
2007-10-07 13:22:07 +08:00
Z_SET_REFCOUNT_P ( varptr , 0 ) ;
2004-10-23 05:42:14 +08:00
} else if ( PZVAL_IS_REF ( varptr ) ) {
zval * original_var = varptr ;
ALLOC_ZVAL ( varptr ) ;
2010-04-20 19:16:39 +08:00
ZVAL_COPY_VALUE ( varptr , original_var ) ;
2007-10-07 13:22:07 +08:00
Z_UNSET_ISREF_P ( varptr ) ;
Z_SET_REFCOUNT_P ( varptr , 0 ) ;
2004-10-23 05:42:14 +08:00
zval_copy_ctor ( varptr ) ;
}
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( varptr ) ;
2008-01-24 17:41:39 +08:00
zend_vm_stack_push ( varptr TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
FREE_OP1 ( ) ; /* for string offsets */
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 106 , ZEND_SEND_VAR_NO_REF , VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2005-09-20 00:02:21 +08:00
zend_free_op free_op1 ;
zval * varptr ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
if ( opline - > extended_value & ZEND_ARG_COMPILE_TIME_BOUND ) { /* Had function_ptr at compile_time */
if ( ! ( opline - > extended_value & ZEND_ARG_SEND_BY_REF ) ) {
ZEND_VM_DISPATCH_TO_HELPER ( zend_send_by_var_helper ) ;
}
2012-11-30 17:39:23 +08:00
} else if ( ! ARG_SHOULD_BE_SENT_BY_REF ( EX ( call ) - > fbc , opline - > op2 . opline_num ) ) {
2004-10-23 05:42:14 +08:00
ZEND_VM_DISPATCH_TO_HELPER ( zend_send_by_var_helper ) ;
}
2006-05-12 05:07:39 +08:00
2006-12-25 22:16:27 +08:00
if ( OP1_TYPE = = IS_VAR & &
( opline - > extended_value & ZEND_ARG_SEND_FUNCTION ) & &
2010-04-20 18:57:45 +08:00
EX_T ( opline - > op1 . var ) . var . fcall_returned_reference & &
EX_T ( opline - > op1 . var ) . var . ptr ) {
varptr = EX_T ( opline - > op1 . var ) . var . ptr ;
2006-12-25 22:16:27 +08:00
PZVAL_UNLOCK_EX ( varptr , & free_op1 , 0 ) ;
} else {
varptr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
}
2005-09-20 00:02:21 +08:00
if ( ( ! ( opline - > extended_value & ZEND_ARG_SEND_FUNCTION ) | |
2010-04-20 18:57:45 +08:00
EX_T ( opline - > op1 . var ) . var . fcall_returned_reference ) & &
2006-05-12 05:07:39 +08:00
varptr ! = & EG ( uninitialized_zval ) & &
( PZVAL_IS_REF ( varptr ) | |
2007-10-07 13:22:07 +08:00
( Z_REFCOUNT_P ( varptr ) = = 1 & & ( OP1_TYPE = = IS_CV | | free_op1 . var ) ) ) ) {
Z_SET_ISREF_P ( varptr ) ;
Z_ADDREF_P ( varptr ) ;
2008-01-24 17:41:39 +08:00
zend_vm_stack_push ( varptr TSRMLS_CC ) ;
2005-06-22 16:33:00 +08:00
} else {
2005-09-20 00:02:21 +08:00
zval * valptr ;
2004-10-23 05:42:14 +08:00
2009-07-28 20:35:27 +08:00
if ( ( opline - > extended_value & ZEND_ARG_COMPILE_TIME_BOUND ) ?
! ( opline - > extended_value & ZEND_ARG_SEND_SILENT ) :
2012-11-30 17:39:23 +08:00
! ARG_MAY_BE_SENT_BY_REF ( EX ( call ) - > fbc , opline - > op2 . opline_num ) ) {
2009-01-20 21:21:52 +08:00
zend_error ( E_STRICT , " Only variables should be passed by reference " ) ;
}
2005-09-20 00:02:21 +08:00
ALLOC_ZVAL ( valptr ) ;
INIT_PZVAL_COPY ( valptr , varptr ) ;
if ( ! IS_OP1_TMP_FREE ( ) ) {
zval_copy_ctor ( valptr ) ;
2004-10-23 05:42:14 +08:00
}
2008-01-24 17:41:39 +08:00
zend_vm_stack_push ( valptr TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
}
2005-09-20 00:02:21 +08:00
FREE_OP1_IF_VAR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 67 , ZEND_SEND_REF , VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
zval * * varptr_ptr ;
zval * varptr ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
varptr_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( varptr_ptr = = NULL ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Only variables can be passed by reference " ) ;
}
2010-07-05 17:08:35 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( * varptr_ptr = = & EG ( error_zval ) ) ) {
2011-03-16 19:14:33 +08:00
ALLOC_INIT_ZVAL ( varptr ) ;
zend_vm_stack_push ( varptr TSRMLS_CC ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2010-07-05 17:08:35 +08:00
}
2012-11-30 17:39:23 +08:00
if ( EX ( function_state ) . function - > type = = ZEND_INTERNAL_FUNCTION & & ! ARG_SHOULD_BE_SENT_BY_REF ( EX ( call ) - > fbc , opline - > op2 . opline_num ) ) {
2010-04-20 19:16:39 +08:00
ZEND_VM_DISPATCH_TO_HELPER ( zend_send_by_var_helper ) ;
}
2009-08-19 04:51:49 +08:00
2004-10-23 05:42:14 +08:00
SEPARATE_ZVAL_TO_MAKE_IS_REF ( varptr_ptr ) ;
varptr = * varptr_ptr ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( varptr ) ;
2008-01-24 17:41:39 +08:00
zend_vm_stack_push ( varptr TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 66 , ZEND_SEND_VAR , VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
if ( ( opline - > extended_value = = ZEND_DO_FCALL_BY_NAME )
2012-11-30 17:39:23 +08:00
& & ARG_SHOULD_BE_SENT_BY_REF ( EX ( call ) - > fbc , opline - > op2 . opline_num ) ) {
2004-10-23 05:42:14 +08:00
ZEND_VM_DISPATCH_TO_HANDLER ( ZEND_SEND_REF ) ;
}
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_DISPATCH_TO_HELPER ( zend_send_by_var_helper ) ;
}
ZEND_VM_HANDLER ( 63 , ZEND_RECV , ANY , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2010-04-20 18:57:45 +08:00
zend_uint arg_num = opline - > op1 . num ;
2008-01-24 17:41:39 +08:00
zval * * param = zend_vm_stack_get_arg ( arg_num TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
if ( UNEXPECTED ( param = = NULL ) ) {
2007-11-03 02:05:55 +08:00
if ( zend_verify_arg_type ( ( zend_function * ) EG ( active_op_array ) , arg_num , NULL , opline - > extended_value TSRMLS_CC ) ) {
2011-09-13 21:29:35 +08:00
const char * space ;
const char * class_name ;
2010-04-20 19:16:39 +08:00
zend_execute_data * ptr ;
2011-03-16 13:25:02 +08:00
2010-04-20 19:16:39 +08:00
if ( EG ( active_op_array ) - > scope ) {
class_name = EG ( active_op_array ) - > scope - > name ;
space = " :: " ;
} else {
class_name = space = " " ;
}
ptr = EX ( prev_execute_data ) ;
2007-11-03 02:05:55 +08:00
if ( ptr & & ptr - > op_array ) {
2010-04-20 18:57:45 +08:00
zend_error ( E_WARNING , " Missing argument %u for %s%s%s(), called in %s on line %d and defined " , opline - > op1 . num , class_name , space , get_active_function_name ( TSRMLS_C ) , ptr - > op_array - > filename , ptr - > opline - > lineno ) ;
2007-11-03 02:05:55 +08:00
} else {
2010-04-20 18:57:45 +08:00
zend_error ( E_WARNING , " Missing argument %u for %s%s%s() " , opline - > op1 . num , class_name , space , get_active_function_name ( TSRMLS_C ) ) ;
2007-11-03 02:05:55 +08:00
}
2004-10-23 05:42:14 +08:00
}
} else {
zval * * var_ptr ;
2007-10-01 18:37:14 +08:00
zend_verify_arg_type ( ( zend_function * ) EG ( active_op_array ) , arg_num , * param , opline - > extended_value TSRMLS_CC ) ;
2012-12-04 14:14:39 +08:00
var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W ( execute_data , opline - > result . var TSRMLS_CC ) ;
2008-04-24 23:45:46 +08:00
Z_DELREF_PP ( var_ptr ) ;
* var_ptr = * param ;
Z_ADDREF_PP ( var_ptr ) ;
2004-10-23 05:42:14 +08:00
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 64 , ZEND_RECV_INIT , ANY , CONST )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2008-04-24 23:45:46 +08:00
zval * assignment_value ;
2010-04-20 18:57:45 +08:00
zend_uint arg_num = opline - > op1 . num ;
2008-01-24 17:41:39 +08:00
zval * * param = zend_vm_stack_get_arg ( arg_num TSRMLS_CC ) ;
2008-05-07 00:59:38 +08:00
zval * * var_ptr ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2008-01-24 17:41:39 +08:00
if ( param = = NULL ) {
2008-04-24 23:45:46 +08:00
ALLOC_ZVAL ( assignment_value ) ;
2010-04-20 18:57:45 +08:00
* assignment_value = * opline - > op2 . zv ;
if ( ( Z_TYPE_P ( assignment_value ) & IS_CONSTANT_TYPE_MASK ) = = IS_CONSTANT | |
Z_TYPE_P ( assignment_value ) = = IS_CONSTANT_ARRAY ) {
2008-04-24 23:45:46 +08:00
Z_SET_REFCOUNT_P ( assignment_value , 1 ) ;
zval_update_constant ( & assignment_value , 0 TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
} else {
2008-04-24 23:45:46 +08:00
zval_copy_ctor ( assignment_value ) ;
2004-10-23 05:42:14 +08:00
}
2008-04-24 23:45:46 +08:00
INIT_PZVAL ( assignment_value ) ;
2004-10-23 05:42:14 +08:00
} else {
assignment_value = * param ;
2008-04-24 23:45:46 +08:00
Z_ADDREF_P ( assignment_value ) ;
2004-10-23 05:42:14 +08:00
}
2008-04-24 23:45:46 +08:00
zend_verify_arg_type ( ( zend_function * ) EG ( active_op_array ) , arg_num , assignment_value , opline - > extended_value TSRMLS_CC ) ;
2012-12-04 14:14:39 +08:00
var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W ( execute_data , opline - > result . var TSRMLS_CC ) ;
2008-04-24 23:45:46 +08:00
Z_DELREF_PP ( var_ptr ) ;
* var_ptr = assignment_value ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 52 , ZEND_BOOL , CONST | TMP | VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
zval * retval = & EX_T ( opline - > result . var ) . tmp_var ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
/* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */
2010-04-20 19:16:39 +08:00
ZVAL_BOOL ( retval , i_zend_is_true ( GET_OP1_ZVAL_PTR ( BP_VAR_R ) ) ) ;
2004-10-23 05:42:14 +08:00
FREE_OP1 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2010-11-24 20:19:56 +08:00
ZEND_VM_HANDLER ( 50 , ZEND_BRK , ANY , CONST )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2005-11-01 03:25:14 +08:00
zend_brk_cont_element * el ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-11-24 20:19:56 +08:00
el = zend_brk_cont ( Z_LVAL_P ( opline - > op2 . zv ) , opline - > op1 . opline_num ,
2012-12-04 14:14:39 +08:00
EX ( op_array ) , execute_data TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2012-11-22 19:17:05 +08:00
ZEND_VM_JMP ( EX ( op_array ) - > opcodes + el - > brk ) ;
2004-10-23 05:42:14 +08:00
}
2010-11-24 20:19:56 +08:00
ZEND_VM_HANDLER ( 51 , ZEND_CONT , ANY , CONST )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2005-11-01 03:25:14 +08:00
zend_brk_cont_element * el ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-11-24 20:19:56 +08:00
el = zend_brk_cont ( Z_LVAL_P ( opline - > op2 . zv ) , opline - > op1 . opline_num ,
2012-12-04 14:14:39 +08:00
EX ( op_array ) , execute_data TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2012-11-22 19:17:05 +08:00
ZEND_VM_JMP ( EX ( op_array ) - > opcodes + el - > cont ) ;
2004-10-23 05:42:14 +08:00
}
2008-03-28 22:35:01 +08:00
ZEND_VM_HANDLER ( 100 , ZEND_GOTO , ANY , CONST )
{
zend_op * brk_opline ;
2010-04-20 19:16:39 +08:00
USE_OPLINE
2008-03-28 22:35:01 +08:00
zend_brk_cont_element * el ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-11-24 20:19:56 +08:00
el = zend_brk_cont ( Z_LVAL_P ( opline - > op2 . zv ) , opline - > extended_value ,
2012-12-04 14:14:39 +08:00
EX ( op_array ) , execute_data TSRMLS_CC ) ;
2008-03-28 22:35:01 +08:00
brk_opline = EX ( op_array ) - > opcodes + el - > brk ;
switch ( brk_opline - > opcode ) {
case ZEND_SWITCH_FREE :
2010-04-20 18:57:45 +08:00
if ( ! ( brk_opline - > extended_value & EXT_TYPE_FREE_ON_RETURN ) ) {
2010-10-22 21:59:23 +08:00
zval_ptr_dtor ( & EX_T ( brk_opline - > op1 . var ) . var . ptr ) ;
2008-05-05 19:03:35 +08:00
}
2008-03-28 22:35:01 +08:00
break ;
case ZEND_FREE :
2010-04-20 18:57:45 +08:00
if ( ! ( brk_opline - > extended_value & EXT_TYPE_FREE_ON_RETURN ) ) {
zendi_zval_dtor ( EX_T ( brk_opline - > op1 . var ) . tmp_var ) ;
2008-05-05 19:03:35 +08:00
}
2008-03-28 22:35:01 +08:00
break ;
}
2012-11-22 19:17:05 +08:00
ZEND_VM_JMP ( opline - > op1 . jmp_addr ) ;
2008-03-28 22:35:01 +08:00
}
2004-10-23 05:42:14 +08:00
ZEND_VM_HANDLER ( 48 , ZEND_CASE , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
if ( OP1_TYPE = = IS_VAR ) {
2010-07-16 19:44:30 +08:00
PZVAL_LOCK ( EX_T ( opline - > op1 . var ) . var . ptr ) ;
2004-10-23 05:42:14 +08:00
}
2010-04-20 18:57:45 +08:00
is_equal_function ( & EX_T ( opline - > result . var ) . tmp_var ,
2004-10-23 05:42:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2008-05-05 19:03:35 +08:00
ZEND_VM_HANDLER ( 49 , ZEND_SWITCH_FREE , VAR , ANY )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2008-01-11 18:08:49 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-10-22 21:59:23 +08:00
zval_ptr_dtor ( & EX_T ( opline - > op1 . var ) . var . ptr ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 68 , ZEND_NEW , ANY , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2005-06-10 15:56:40 +08:00
zval * object_zval ;
zend_function * constructor ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
if ( UNEXPECTED ( ( EX_T ( opline - > op1 . var ) . class_entry - > ce_flags & ( ZEND_ACC_INTERFACE | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS ) ) ! = 0 ) ) {
2010-04-20 18:57:45 +08:00
if ( EX_T ( opline - > op1 . var ) . class_entry - > ce_flags & ZEND_ACC_INTERFACE ) {
2010-05-06 20:52:27 +08:00
zend_error_noreturn ( E_ERROR , " Cannot instantiate interface %s " , EX_T ( opline - > op1 . var ) . class_entry - > name ) ;
2010-05-07 19:09:35 +08:00
} else if ( ( EX_T ( opline - > op1 . var ) . class_entry - > ce_flags & ZEND_ACC_TRAIT ) = = ZEND_ACC_TRAIT ) {
2010-05-06 20:52:27 +08:00
zend_error_noreturn ( E_ERROR , " Cannot instantiate trait %s " , EX_T ( opline - > op1 . var ) . class_entry - > name ) ;
2004-10-23 05:42:14 +08:00
} else {
2010-05-06 20:52:27 +08:00
zend_error_noreturn ( E_ERROR , " Cannot instantiate abstract class %s " , EX_T ( opline - > op1 . var ) . class_entry - > name ) ;
2004-10-23 05:42:14 +08:00
}
}
2005-06-10 15:56:40 +08:00
ALLOC_ZVAL ( object_zval ) ;
2010-04-20 18:57:45 +08:00
object_init_ex ( object_zval , EX_T ( opline - > op1 . var ) . class_entry ) ;
2005-06-10 15:56:40 +08:00
INIT_PZVAL ( object_zval ) ;
2004-10-23 05:42:14 +08:00
2005-06-10 15:56:40 +08:00
constructor = Z_OBJ_HT_P ( object_zval ) - > get_constructor ( object_zval TSRMLS_CC ) ;
if ( constructor = = NULL ) {
if ( RETURN_VALUE_USED ( opline ) ) {
2010-04-20 19:16:39 +08:00
AI_SET_PTR ( & EX_T ( opline - > result . var ) , object_zval ) ;
2005-06-10 15:56:40 +08:00
} else {
zval_ptr_dtor ( & object_zval ) ;
}
2010-04-20 18:57:45 +08:00
ZEND_VM_JMP ( EX ( op_array ) - > opcodes + opline - > op2 . opline_num ) ;
2005-06-10 15:56:40 +08:00
} else {
2012-11-30 17:39:23 +08:00
call_slot * call = EX ( call_slots ) + opline - > extended_value ;
2007-12-14 22:14:50 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
PZVAL_LOCK ( object_zval ) ;
2010-04-20 19:16:39 +08:00
AI_SET_PTR ( & EX_T ( opline - > result . var ) , object_zval ) ;
2007-12-14 22:14:50 +08:00
}
2006-05-12 05:07:39 +08:00
2005-06-10 15:56:40 +08:00
/* We are not handling overloaded classes right now */
2012-11-30 17:39:23 +08:00
call - > fbc = constructor ;
call - > object = object_zval ;
call - > called_scope = EX_T ( opline - > op1 . var ) . class_entry ;
call - > is_ctor_call = 1 ;
call - > is_ctor_result_used = RETURN_VALUE_USED ( opline ) ;
EX ( call ) = call ;
2005-06-10 15:56:40 +08:00
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2005-06-10 15:56:40 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
}
ZEND_VM_HANDLER ( 110 , ZEND_CLONE , CONST | TMP | VAR | UNUSED | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
zval * obj ;
2004-10-23 05:42:14 +08:00
zend_class_entry * ce ;
zend_function * clone ;
zend_object_clone_obj_t clone_call ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
obj = GET_OP1_OBJ_ZVAL_PTR ( BP_VAR_R ) ;
2009-04-08 21:19:34 +08:00
if ( OP1_TYPE = = IS_CONST | |
2010-04-20 19:16:39 +08:00
UNEXPECTED ( Z_TYPE_P ( obj ) ! = IS_OBJECT ) ) {
2007-10-05 07:19:20 +08:00
zend_error_noreturn ( E_ERROR , " __clone method called on non-object " ) ;
2004-10-23 05:42:14 +08:00
}
ce = Z_OBJCE_P ( obj ) ;
clone = ce ? ce - > clone : NULL ;
clone_call = Z_OBJ_HT_P ( obj ) - > clone_obj ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( clone_call = = NULL ) ) {
2006-07-27 18:44:03 +08:00
if ( ce ) {
zend_error_noreturn ( E_ERROR , " Trying to clone an uncloneable object of class %s " , ce - > name ) ;
} else {
zend_error_noreturn ( E_ERROR , " Trying to clone an uncloneable object " ) ;
}
2004-10-23 05:42:14 +08:00
}
if ( ce & & clone ) {
if ( clone - > op_array . fn_flags & ZEND_ACC_PRIVATE ) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( ce ! = EG ( scope ) ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Call to private %s::__clone() from context '%s' " , ce - > name , EG ( scope ) ? EG ( scope ) - > name : " " ) ;
}
} else if ( ( clone - > common . fn_flags & ZEND_ACC_PROTECTED ) ) {
/* Ensure that if we're calling a protected function, we're allowed to do so.
*/
2012-05-13 13:12:48 +08:00
if ( UNEXPECTED ( ! zend_check_protected ( zend_get_function_root_class ( clone ) , EG ( scope ) ) ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Call to protected %s::__clone() from context '%s' " , ce - > name , EG ( scope ) ? EG ( scope ) - > name : " " ) ;
}
}
}
2010-04-20 19:16:39 +08:00
if ( EXPECTED ( EG ( exception ) = = NULL ) ) {
zval * retval ;
ALLOC_ZVAL ( retval ) ;
Z_OBJVAL_P ( retval ) = clone_call ( obj TSRMLS_CC ) ;
Z_TYPE_P ( retval ) = IS_OBJECT ;
Z_SET_REFCOUNT_P ( retval , 1 ) ;
Z_SET_ISREF_P ( retval ) ;
if ( ! RETURN_VALUE_USED ( opline ) | | UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
zval_ptr_dtor ( & retval ) ;
} else {
AI_SET_PTR ( & EX_T ( opline - > result . var ) , retval ) ;
2006-06-08 16:56:27 +08:00
}
2004-10-23 05:42:14 +08:00
}
FREE_OP1_IF_VAR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2007-09-29 03:52:53 +08:00
ZEND_VM_HANDLER ( 99 , ZEND_FETCH_CONSTANT , VAR | CONST | UNUSED , CONST )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
if ( OP1_TYPE = = IS_UNUSED ) {
2010-04-27 20:09:13 +08:00
zend_constant * c ;
zval * retval ;
2010-05-24 22:11:39 +08:00
if ( CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ) {
c = CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ;
} else if ( ( c = zend_quick_get_constant ( opline - > op2 . literal + 1 , opline - > extended_value TSRMLS_CC ) ) = = NULL ) {
2008-11-12 03:45:29 +08:00
if ( ( opline - > extended_value & IS_CONSTANT_UNQUALIFIED ) ! = 0 ) {
2010-04-20 18:57:45 +08:00
char * actual = ( char * ) zend_memrchr ( Z_STRVAL_P ( opline - > op2 . zv ) , ' \\ ' , Z_STRLEN_P ( opline - > op2 . zv ) ) ;
2008-11-12 03:45:29 +08:00
if ( ! actual ) {
2010-04-20 18:57:45 +08:00
actual = Z_STRVAL_P ( opline - > op2 . zv ) ;
2008-11-12 03:45:29 +08:00
} else {
actual + + ;
2008-11-04 23:58:55 +08:00
}
2008-11-12 03:45:29 +08:00
/* non-qualified constant - allow text substitution */
zend_error ( E_NOTICE , " Use of undefined constant %s - assumed '%s' " , actual , actual ) ;
2010-04-20 18:57:45 +08:00
ZVAL_STRINGL ( & EX_T ( opline - > result . var ) . tmp_var , actual , Z_STRLEN_P ( opline - > op2 . zv ) - ( actual - Z_STRVAL_P ( opline - > op2 . zv ) ) , 1 ) ;
2010-04-27 20:09:13 +08:00
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2008-11-04 23:58:55 +08:00
} else {
2010-04-20 19:16:39 +08:00
zend_error_noreturn ( E_ERROR , " Undefined constant '%s' " , Z_STRVAL_P ( opline - > op2 . zv ) ) ;
2007-12-08 01:11:24 +08:00
}
2010-05-24 22:11:39 +08:00
} else {
CACHE_PTR ( opline - > op2 . literal - > cache_slot , c ) ;
2004-10-23 05:42:14 +08:00
}
2010-04-27 20:09:13 +08:00
retval = & EX_T ( opline - > result . var ) . tmp_var ;
2010-08-10 23:24:19 +08:00
ZVAL_COPY_VALUE ( retval , & c - > value ) ;
2010-04-27 20:09:13 +08:00
zval_copy_ctor ( retval ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
2007-09-29 03:52:53 +08:00
} else {
2008-11-04 23:58:55 +08:00
/* class constant */
2007-09-29 03:52:53 +08:00
zend_class_entry * ce ;
zval * * value ;
2007-10-03 14:49:15 +08:00
2007-09-29 03:52:53 +08:00
if ( OP1_TYPE = = IS_CONST ) {
2010-05-24 22:11:39 +08:00
if ( CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ) {
value = CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ;
ZVAL_COPY_VALUE ( & EX_T ( opline - > result . var ) . tmp_var , * value ) ;
zval_copy_ctor ( & EX_T ( opline - > result . var ) . tmp_var ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( CACHED_PTR ( opline - > op1 . literal - > cache_slot ) ) {
ce = CACHED_PTR ( opline - > op1 . literal - > cache_slot ) ;
} else {
ce = zend_fetch_class_by_name ( Z_STRVAL_P ( opline - > op1 . zv ) , Z_STRLEN_P ( opline - > op1 . zv ) , opline - > op1 . literal + 1 , opline - > extended_value TSRMLS_CC ) ;
if ( UNEXPECTED ( ce = = NULL ) ) {
2012-02-25 21:56:59 +08:00
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2010-05-24 22:11:39 +08:00
}
CACHE_PTR ( opline - > op1 . literal - > cache_slot , ce ) ;
2007-09-29 03:52:53 +08:00
}
} else {
2010-04-20 18:57:45 +08:00
ce = EX_T ( opline - > op1 . var ) . class_entry ;
2010-05-24 22:11:39 +08:00
if ( ( value = CACHED_POLYMORPHIC_PTR ( opline - > op2 . literal - > cache_slot , ce ) ) ! = NULL ) {
ZVAL_COPY_VALUE ( & EX_T ( opline - > result . var ) . tmp_var , * value ) ;
zval_copy_ctor ( & EX_T ( opline - > result . var ) . tmp_var ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2007-09-29 03:52:53 +08:00
}
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
if ( EXPECTED ( zend_hash_quick_find ( & ce - > constants_table , Z_STRVAL_P ( opline - > op2 . zv ) , Z_STRLEN_P ( opline - > op2 . zv ) + 1 , Z_HASH_P ( opline - > op2 . zv ) , ( void * * ) & value ) = = SUCCESS ) ) {
2007-09-29 03:52:53 +08:00
if ( Z_TYPE_PP ( value ) = = IS_CONSTANT_ARRAY | |
2007-10-02 16:26:50 +08:00
( Z_TYPE_PP ( value ) & IS_CONSTANT_TYPE_MASK ) = = IS_CONSTANT ) {
2007-09-29 03:52:53 +08:00
zend_class_entry * old_scope = EG ( scope ) ;
2004-10-23 05:42:14 +08:00
2007-09-29 03:52:53 +08:00
EG ( scope ) = ce ;
zval_update_constant ( value , ( void * ) 1 TSRMLS_CC ) ;
EG ( scope ) = old_scope ;
}
2010-05-24 22:11:39 +08:00
if ( OP1_TYPE = = IS_CONST ) {
CACHE_PTR ( opline - > op2 . literal - > cache_slot , value ) ;
} else {
CACHE_POLYMORPHIC_PTR ( opline - > op2 . literal - > cache_slot , ce , value ) ;
}
2010-04-20 19:16:39 +08:00
ZVAL_COPY_VALUE ( & EX_T ( opline - > result . var ) . tmp_var , * value ) ;
2010-04-20 18:57:45 +08:00
zval_copy_ctor ( & EX_T ( opline - > result . var ) . tmp_var ) ;
2007-09-29 03:52:53 +08:00
} else {
2010-04-20 18:57:45 +08:00
zend_error_noreturn ( E_ERROR , " Undefined class constant '%s' " , Z_STRVAL_P ( opline - > op2 . zv ) ) ;
2007-09-29 03:52:53 +08:00
}
2007-06-13 22:50:13 +08:00
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2007-09-29 03:52:53 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
2004-10-23 05:42:14 +08:00
}
}
2006-09-18 22:23:52 +08:00
ZEND_VM_HANDLER ( 72 , ZEND_ADD_ARRAY_ELEMENT , CONST | TMP | VAR | CV , CONST | TMP | VAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
zend_free_op free_op1 ;
2006-06-08 16:37:51 +08:00
zval * expr_ptr ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
if ( ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) & & opline - > extended_value ) {
zval * * expr_ptr_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2006-06-08 16:37:51 +08:00
2010-10-22 19:05:22 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( expr_ptr_ptr = = NULL ) ) {
zend_error_noreturn ( E_ERROR , " Cannot create references to/from string offsets " ) ;
}
2010-04-20 19:16:39 +08:00
SEPARATE_ZVAL_TO_MAKE_IS_REF ( expr_ptr_ptr ) ;
2004-10-23 05:42:14 +08:00
expr_ptr = * expr_ptr_ptr ;
2010-04-20 19:16:39 +08:00
Z_ADDREF_P ( expr_ptr ) ;
2004-10-23 05:42:14 +08:00
} else {
expr_ptr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2010-04-20 19:16:39 +08:00
if ( IS_OP1_TMP_FREE ( ) ) { /* temporary variable */
zval * new_expr ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
ALLOC_ZVAL ( new_expr ) ;
INIT_PZVAL_COPY ( new_expr , expr_ptr ) ;
expr_ptr = new_expr ;
} else if ( OP1_TYPE = = IS_CONST | | PZVAL_IS_REF ( expr_ptr ) ) {
2004-10-23 05:42:14 +08:00
zval * new_expr ;
ALLOC_ZVAL ( new_expr ) ;
INIT_PZVAL_COPY ( new_expr , expr_ptr ) ;
expr_ptr = new_expr ;
zendi_zval_copy_ctor ( * expr_ptr ) ;
} else {
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( expr_ptr ) ;
2004-10-23 05:42:14 +08:00
}
}
2010-04-20 19:16:39 +08:00
if ( OP2_TYPE ! = IS_UNUSED ) {
zend_free_op free_op2 ;
zval * offset = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
ulong hval ;
2011-03-16 13:25:02 +08:00
2006-05-12 05:07:39 +08:00
switch ( Z_TYPE_P ( offset ) ) {
2004-10-23 05:42:14 +08:00
case IS_DOUBLE :
2010-10-05 19:28:56 +08:00
hval = zend_dval_to_lval ( Z_DVAL_P ( offset ) ) ;
2010-04-20 18:57:45 +08:00
ZEND_VM_C_GOTO ( num_index ) ;
2004-10-23 05:42:14 +08:00
case IS_LONG :
case IS_BOOL :
2010-10-05 19:28:56 +08:00
hval = Z_LVAL_P ( offset ) ;
2010-04-20 18:57:45 +08:00
ZEND_VM_C_LABEL ( num_index ) :
2010-10-05 19:28:56 +08:00
zend_hash_index_update ( Z_ARRVAL ( EX_T ( opline - > result . var ) . tmp_var ) , hval , & expr_ptr , sizeof ( zval * ) , NULL ) ;
2004-10-23 05:42:14 +08:00
break ;
case IS_STRING :
2010-04-20 18:57:45 +08:00
if ( OP2_TYPE = = IS_CONST ) {
hval = Z_HASH_P ( offset ) ;
} else {
2010-10-05 19:28:56 +08:00
ZEND_HANDLE_NUMERIC_EX ( Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 , hval , ZEND_VM_C_GOTO ( num_index ) ) ;
2010-04-20 19:05:54 +08:00
if ( IS_INTERNED ( Z_STRVAL_P ( offset ) ) ) {
hval = INTERNED_HASH ( Z_STRVAL_P ( offset ) ) ;
} else {
hval = zend_hash_func ( Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 ) ;
}
2010-04-20 18:57:45 +08:00
}
2010-04-20 19:16:39 +08:00
zend_hash_quick_update ( Z_ARRVAL ( EX_T ( opline - > result . var ) . tmp_var ) , Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 , hval , & expr_ptr , sizeof ( zval * ) , NULL ) ;
2004-10-23 05:42:14 +08:00
break ;
case IS_NULL :
2010-04-20 19:16:39 +08:00
zend_hash_update ( Z_ARRVAL ( EX_T ( opline - > result . var ) . tmp_var ) , " " , sizeof ( " " ) , & expr_ptr , sizeof ( zval * ) , NULL ) ;
2004-10-23 05:42:14 +08:00
break ;
default :
zend_error ( E_WARNING , " Illegal offset type " ) ;
zval_ptr_dtor ( & expr_ptr ) ;
/* do nothing */
break ;
}
FREE_OP2 ( ) ;
} else {
2010-04-20 19:16:39 +08:00
zend_hash_next_index_insert ( Z_ARRVAL ( EX_T ( opline - > result . var ) . tmp_var ) , & expr_ptr , sizeof ( zval * ) , NULL ) ;
2004-10-23 05:42:14 +08:00
}
2010-04-20 19:16:39 +08:00
if ( ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) & & opline - > extended_value ) {
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
} else {
FREE_OP1_IF_VAR ( ) ;
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 71 , ZEND_INIT_ARRAY , CONST | TMP | VAR | UNUSED | CV , CONST | TMP | VAR | UNUSED | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2006-09-18 22:23:52 +08:00
2010-04-20 18:57:45 +08:00
array_init ( & EX_T ( opline - > result . var ) . tmp_var ) ;
2006-09-18 22:23:52 +08:00
if ( OP1_TYPE = = IS_UNUSED ) {
ZEND_VM_NEXT_OPCODE ( ) ;
# if !defined(ZEND_VM_SPEC) || OP1_TYPE != IS_UNUSED
} else {
ZEND_VM_DISPATCH_TO_HANDLER ( ZEND_ADD_ARRAY_ELEMENT ) ;
# endif
}
2004-10-23 05:42:14 +08:00
}
ZEND_VM_HANDLER ( 21 , ZEND_CAST , CONST | TMP | VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
zval * expr ;
2010-04-20 18:57:45 +08:00
zval * result = & EX_T ( opline - > result . var ) . tmp_var ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
expr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2007-10-03 16:02:36 +08:00
if ( opline - > extended_value ! = IS_STRING ) {
2010-04-20 19:16:39 +08:00
ZVAL_COPY_VALUE ( result , expr ) ;
2007-10-03 16:02:36 +08:00
if ( ! IS_OP1_TMP_FREE ( ) ) {
zendi_zval_copy_ctor ( * result ) ;
}
2004-10-23 05:42:14 +08:00
}
switch ( opline - > extended_value ) {
case IS_NULL :
convert_to_null ( result ) ;
break ;
case IS_BOOL :
convert_to_boolean ( result ) ;
break ;
case IS_LONG :
convert_to_long ( result ) ;
break ;
case IS_DOUBLE :
convert_to_double ( result ) ;
break ;
case IS_STRING : {
zval var_copy ;
int use_copy ;
2007-10-03 16:02:36 +08:00
zend_make_printable_zval ( expr , & var_copy , & use_copy ) ;
2004-10-23 05:42:14 +08:00
if ( use_copy ) {
2010-04-20 19:16:39 +08:00
ZVAL_COPY_VALUE ( result , & var_copy ) ;
2007-10-03 16:02:36 +08:00
if ( IS_OP1_TMP_FREE ( ) ) {
FREE_OP1 ( ) ;
}
} else {
2010-04-20 19:16:39 +08:00
ZVAL_COPY_VALUE ( result , expr ) ;
2007-10-03 16:02:36 +08:00
if ( ! IS_OP1_TMP_FREE ( ) ) {
zendi_zval_copy_ctor ( * result ) ;
}
2004-10-23 05:42:14 +08:00
}
break ;
}
case IS_ARRAY :
convert_to_array ( result ) ;
break ;
case IS_OBJECT :
convert_to_object ( result ) ;
break ;
}
FREE_OP1_IF_VAR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 73 , ZEND_INCLUDE_OR_EVAL , CONST | TMP | VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_op_array * new_op_array = NULL ;
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
zval * inc_filename ;
2012-08-14 08:59:40 +08:00
zval * tmp_inc_filename = NULL ;
2004-10-23 05:42:14 +08:00
zend_bool failure_retval = 0 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
inc_filename = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
if ( inc_filename - > type ! = IS_STRING ) {
2012-01-24 22:39:45 +08:00
MAKE_STD_ZVAL ( tmp_inc_filename ) ;
ZVAL_COPY_VALUE ( tmp_inc_filename , inc_filename ) ;
zval_copy_ctor ( tmp_inc_filename ) ;
convert_to_string ( tmp_inc_filename ) ;
inc_filename = tmp_inc_filename ;
2004-10-23 05:42:14 +08:00
}
2011-06-07 05:28:16 +08:00
if ( opline - > extended_value ! = ZEND_EVAL & & strlen ( Z_STRVAL_P ( inc_filename ) ) ! = Z_STRLEN_P ( inc_filename ) ) {
if ( opline - > extended_value = = ZEND_INCLUDE_ONCE | | opline - > extended_value = = ZEND_INCLUDE ) {
zend_message_dispatcher ( ZMSG_FAILED_INCLUDE_FOPEN , Z_STRVAL_P ( inc_filename ) TSRMLS_CC ) ;
} else {
zend_message_dispatcher ( ZMSG_FAILED_REQUIRE_FOPEN , Z_STRVAL_P ( inc_filename ) TSRMLS_CC ) ;
}
} else {
switch ( opline - > extended_value ) {
case ZEND_INCLUDE_ONCE :
case ZEND_REQUIRE_ONCE : {
zend_file_handle file_handle ;
char * resolved_path ;
resolved_path = zend_resolve_path ( Z_STRVAL_P ( inc_filename ) , Z_STRLEN_P ( inc_filename ) TSRMLS_CC ) ;
if ( resolved_path ) {
failure_retval = zend_hash_exists ( & EG ( included_files ) , resolved_path , strlen ( resolved_path ) + 1 ) ;
} else {
resolved_path = Z_STRVAL_P ( inc_filename ) ;
2004-10-23 05:42:14 +08:00
}
2011-06-07 05:28:16 +08:00
if ( failure_retval ) {
/* do nothing, file already included */
} else if ( SUCCESS = = zend_stream_open ( resolved_path , & file_handle TSRMLS_CC ) ) {
if ( ! file_handle . opened_path ) {
file_handle . opened_path = estrdup ( resolved_path ) ;
}
if ( zend_hash_add_empty_element ( & EG ( included_files ) , file_handle . opened_path , strlen ( file_handle . opened_path ) + 1 ) = = SUCCESS ) {
new_op_array = zend_compile_file ( & file_handle , ( opline - > extended_value = = ZEND_INCLUDE_ONCE ? ZEND_INCLUDE : ZEND_REQUIRE ) TSRMLS_CC ) ;
zend_destroy_file_handle ( & file_handle TSRMLS_CC ) ;
} else {
zend_file_handle_dtor ( & file_handle TSRMLS_CC ) ;
failure_retval = 1 ;
}
2004-10-23 05:42:14 +08:00
} else {
2011-06-07 05:28:16 +08:00
if ( opline - > extended_value = = ZEND_INCLUDE_ONCE ) {
zend_message_dispatcher ( ZMSG_FAILED_INCLUDE_FOPEN , Z_STRVAL_P ( inc_filename ) TSRMLS_CC ) ;
} else {
zend_message_dispatcher ( ZMSG_FAILED_REQUIRE_FOPEN , Z_STRVAL_P ( inc_filename ) TSRMLS_CC ) ;
}
2004-10-23 05:42:14 +08:00
}
2011-06-07 05:28:16 +08:00
if ( resolved_path ! = Z_STRVAL_P ( inc_filename ) ) {
efree ( resolved_path ) ;
2004-10-23 05:42:14 +08:00
}
}
2011-06-07 05:28:16 +08:00
break ;
case ZEND_INCLUDE :
case ZEND_REQUIRE :
new_op_array = compile_filename ( opline - > extended_value , inc_filename TSRMLS_CC ) ;
break ;
case ZEND_EVAL : {
char * eval_desc = zend_make_compiled_string_description ( " eval()'d code " TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2011-06-07 05:28:16 +08:00
new_op_array = zend_compile_string ( inc_filename , eval_desc TSRMLS_CC ) ;
efree ( eval_desc ) ;
}
break ;
EMPTY_SWITCH_DEFAULT_CASE ( )
}
2004-10-23 05:42:14 +08:00
}
2012-01-24 22:39:45 +08:00
if ( tmp_inc_filename ) {
zval_ptr_dtor ( & tmp_inc_filename ) ;
2004-10-23 05:42:14 +08:00
}
2008-06-11 21:18:41 +08:00
FREE_OP1 ( ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
} else if ( EXPECTED ( new_op_array ! = NULL ) ) {
2008-06-11 21:18:41 +08:00
EX ( original_return_value ) = EG ( return_value_ptr_ptr ) ;
2004-10-23 05:42:14 +08:00
EG ( active_op_array ) = new_op_array ;
2010-04-20 19:16:39 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
EX_T ( opline - > result . var ) . var . ptr = NULL ;
EX_T ( opline - > result . var ) . var . ptr_ptr = & EX_T ( opline - > result . var ) . var . ptr ;
EG ( return_value_ptr_ptr ) = EX_T ( opline - > result . var ) . var . ptr_ptr ;
} else {
EG ( return_value_ptr_ptr ) = NULL ;
}
2004-10-23 05:42:14 +08:00
EX ( function_state ) . function = ( zend_function * ) new_op_array ;
EX ( object ) = NULL ;
2008-04-29 16:15:20 +08:00
if ( ! EG ( active_symbol_table ) ) {
zend_rebuild_symbol_table ( TSRMLS_C ) ;
}
2012-11-30 17:39:23 +08:00
if ( EXPECTED ( zend_execute_ex = = execute_ex ) ) {
2008-06-11 21:18:41 +08:00
ZEND_VM_ENTER ( ) ;
} else {
zend_execute ( new_op_array TSRMLS_CC ) ;
}
2004-10-23 05:42:14 +08:00
2008-06-11 21:18:41 +08:00
EX ( function_state ) . function = ( zend_function * ) EX ( op_array ) ;
2004-10-23 05:42:14 +08:00
EG ( opline_ptr ) = & EX ( opline ) ;
EG ( active_op_array ) = EX ( op_array ) ;
2008-06-11 21:18:41 +08:00
EG ( return_value_ptr_ptr ) = EX ( original_return_value ) ;
2004-10-23 05:42:14 +08:00
destroy_op_array ( new_op_array TSRMLS_CC ) ;
efree ( new_op_array ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2004-10-23 05:42:14 +08:00
zend_throw_exception_internal ( NULL TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
HANDLE_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
2010-04-20 19:16:39 +08:00
} else if ( RETURN_VALUE_USED ( opline ) ) {
zval * retval ;
ALLOC_ZVAL ( retval ) ;
ZVAL_BOOL ( retval , failure_retval ) ;
INIT_PZVAL ( retval ) ;
AI_SET_PTR ( & EX_T ( opline - > result . var ) , retval ) ;
2004-10-23 05:42:14 +08:00
}
ZEND_VM_NEXT_OPCODE ( ) ;
}
2010-05-06 18:27:35 +08:00
ZEND_VM_HANDLER ( 74 , ZEND_UNSET_VAR , CONST | TMP | VAR | CV , UNUSED | CONST | VAR )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zval tmp , * varname ;
HashTable * target_symbol_table ;
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-07-27 17:50:35 +08:00
if ( OP1_TYPE = = IS_CV & &
OP2_TYPE = = IS_UNUSED & &
( opline - > extended_value & ZEND_QUICK_SET ) ) {
2008-04-29 16:15:20 +08:00
if ( EG ( active_symbol_table ) ) {
2010-04-20 18:57:45 +08:00
zend_compiled_variable * cv = & CV_DEF_OF ( opline - > op1 . var ) ;
2008-04-29 16:15:20 +08:00
2010-04-20 19:16:39 +08:00
zend_delete_variable ( EX ( prev_execute_data ) , EG ( active_symbol_table ) , cv - > name , cv - > name_len + 1 , cv - > hash_value TSRMLS_CC ) ;
EX_CV ( opline - > op1 . var ) = NULL ;
} else if ( EX_CV ( opline - > op1 . var ) ) {
zval_ptr_dtor ( EX_CV ( opline - > op1 . var ) ) ;
EX_CV ( opline - > op1 . var ) = NULL ;
2008-04-29 16:15:20 +08:00
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2008-04-29 16:15:20 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
varname = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2010-04-20 18:57:45 +08:00
if ( OP1_TYPE ! = IS_CONST & & Z_TYPE_P ( varname ) ! = IS_STRING ) {
2010-04-20 19:16:39 +08:00
ZVAL_COPY_VALUE ( & tmp , varname ) ;
2004-10-23 05:42:14 +08:00
zval_copy_ctor ( & tmp ) ;
convert_to_string ( & tmp ) ;
varname = & tmp ;
2008-05-12 17:09:05 +08:00
} else if ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) {
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( varname ) ;
2004-10-23 05:42:14 +08:00
}
2010-05-06 18:27:35 +08:00
if ( OP2_TYPE ! = IS_UNUSED ) {
zend_class_entry * ce ;
if ( OP2_TYPE = = IS_CONST ) {
2010-05-24 22:11:39 +08:00
if ( CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ) {
ce = CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ;
} else {
ce = zend_fetch_class_by_name ( Z_STRVAL_P ( opline - > op2 . zv ) , Z_STRLEN_P ( opline - > op2 . zv ) , opline - > op2 . literal + 1 , 0 TSRMLS_CC ) ;
2012-02-25 21:56:59 +08:00
if ( UNEXPECTED ( ce = = NULL ) ) {
if ( OP1_TYPE ! = IS_CONST & & varname = = & tmp ) {
zval_dtor ( & tmp ) ;
} else if ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) {
zval_ptr_dtor ( & varname ) ;
}
FREE_OP1 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2010-05-24 22:11:39 +08:00
CACHE_PTR ( opline - > op2 . literal - > cache_slot , ce ) ;
}
2010-05-06 18:27:35 +08:00
} else {
ce = EX_T ( opline - > op2 . var ) . class_entry ;
}
zend_std_unset_static_property ( ce , Z_STRVAL_P ( varname ) , Z_STRLEN_P ( varname ) , ( ( OP1_TYPE = = IS_CONST ) ? opline - > op1 . literal : NULL ) TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
} else {
2008-04-29 16:15:20 +08:00
ulong hash_value = zend_inline_hash_func ( varname - > value . str . val , varname - > value . str . len + 1 ) ;
2010-04-20 18:57:45 +08:00
target_symbol_table = zend_get_target_symbol_table ( opline - > extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC ) ;
2012-12-04 14:14:39 +08:00
zend_delete_variable ( execute_data , target_symbol_table , varname - > value . str . val , varname - > value . str . len + 1 , hash_value TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
}
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE ! = IS_CONST & & varname = = & tmp ) {
2004-10-23 05:42:14 +08:00
zval_dtor ( & tmp ) ;
2008-05-12 17:09:05 +08:00
} else if ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) {
2006-07-26 17:24:26 +08:00
zval_ptr_dtor ( & varname ) ;
2004-10-23 05:42:14 +08:00
}
FREE_OP1 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2005-06-16 20:17:39 +08:00
ZEND_VM_HANDLER ( 75 , ZEND_UNSET_DIM , VAR | UNUSED | CV , CONST | TMP | VAR | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
zval * * container ;
zval * offset ;
2010-04-20 18:57:45 +08:00
ulong hval ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
container = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_UNSET ) ;
2011-04-25 15:50:07 +08:00
if ( OP1_TYPE = = IS_CV & & container ! = & EG ( uninitialized_zval_ptr ) ) {
SEPARATE_ZVAL_IF_NOT_REF ( container ) ;
}
2010-04-20 19:16:39 +08:00
offset = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2011-03-16 13:25:02 +08:00
2009-03-18 20:53:17 +08:00
if ( OP1_TYPE ! = IS_VAR | | container ) {
2005-06-16 20:17:39 +08:00
switch ( Z_TYPE_PP ( container ) ) {
case IS_ARRAY : {
HashTable * ht = Z_ARRVAL_PP ( container ) ;
2006-05-12 05:07:39 +08:00
switch ( Z_TYPE_P ( offset ) ) {
2005-06-16 20:17:39 +08:00
case IS_DOUBLE :
2010-10-05 19:28:56 +08:00
hval = zend_dval_to_lval ( Z_DVAL_P ( offset ) ) ;
2012-07-26 13:52:42 +08:00
zend_hash_index_del ( ht , hval ) ;
break ;
2005-06-16 20:17:39 +08:00
case IS_RESOURCE :
case IS_BOOL :
case IS_LONG :
2010-10-05 19:28:56 +08:00
hval = Z_LVAL_P ( offset ) ;
zend_hash_index_del ( ht , hval ) ;
2005-06-16 20:17:39 +08:00
break ;
case IS_STRING :
2006-07-26 17:24:26 +08:00
if ( OP2_TYPE = = IS_CV | | OP2_TYPE = = IS_VAR ) {
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( offset ) ;
2006-07-26 17:24:26 +08:00
}
2010-04-20 18:57:45 +08:00
if ( OP2_TYPE = = IS_CONST ) {
hval = Z_HASH_P ( offset ) ;
} else {
2010-10-05 19:28:56 +08:00
ZEND_HANDLE_NUMERIC_EX ( Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 , hval , ZEND_VM_C_GOTO ( num_index_dim ) ) ;
2010-04-20 19:05:54 +08:00
if ( IS_INTERNED ( Z_STRVAL_P ( offset ) ) ) {
hval = INTERNED_HASH ( Z_STRVAL_P ( offset ) ) ;
} else {
hval = zend_hash_func ( Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 ) ;
}
2010-04-20 18:57:45 +08:00
}
2010-04-20 19:16:39 +08:00
if ( ht = = & EG ( symbol_table ) ) {
zend_delete_global_variable_ex ( offset - > value . str . val , offset - > value . str . len , hval TSRMLS_CC ) ;
} else {
zend_hash_quick_del ( ht , Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 , hval ) ;
2005-06-16 20:17:39 +08:00
}
2006-07-26 17:24:26 +08:00
if ( OP2_TYPE = = IS_CV | | OP2_TYPE = = IS_VAR ) {
zval_ptr_dtor ( & offset ) ;
}
2005-06-16 20:17:39 +08:00
break ;
2011-07-06 20:04:02 +08:00
ZEND_VM_C_LABEL ( num_index_dim ) :
zend_hash_index_del ( ht , hval ) ;
if ( OP2_TYPE = = IS_CV | | OP2_TYPE = = IS_VAR ) {
zval_ptr_dtor ( & offset ) ;
}
break ;
2005-06-16 20:17:39 +08:00
case IS_NULL :
zend_hash_del ( ht , " " , sizeof ( " " ) ) ;
break ;
default :
zend_error ( E_WARNING , " Illegal offset type in unset " ) ;
break ;
2005-06-03 19:16:19 +08:00
}
2005-06-16 20:17:39 +08:00
FREE_OP2 ( ) ;
break ;
2004-10-23 05:42:14 +08:00
}
2005-06-16 20:17:39 +08:00
case IS_OBJECT :
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( Z_OBJ_HT_P ( * container ) - > unset_dimension = = NULL ) ) {
2005-06-16 20:17:39 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use object as array " ) ;
}
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
MAKE_REAL_ZVAL_PTR ( offset ) ;
}
2005-06-16 20:17:39 +08:00
Z_OBJ_HT_P ( * container ) - > unset_dimension ( * container , offset TSRMLS_CC ) ;
2005-06-03 19:16:19 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
zval_ptr_dtor ( & offset ) ;
} else {
FREE_OP2 ( ) ;
}
2005-06-16 20:17:39 +08:00
break ;
case IS_STRING :
zend_error_noreturn ( E_ERROR , " Cannot unset string offsets " ) ;
ZEND_VM_CONTINUE ( ) ; /* bailed out before */
default :
FREE_OP2 ( ) ;
break ;
}
} else {
FREE_OP2 ( ) ;
}
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2005-06-16 20:17:39 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 76 , ZEND_UNSET_OBJ , VAR | UNUSED | CV , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2005-06-16 20:17:39 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
zval * * container ;
zval * offset ;
SAVE_OPLINE ( ) ;
container = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_UNSET ) ;
offset = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2005-06-16 20:17:39 +08:00
2009-03-18 20:53:17 +08:00
if ( OP1_TYPE ! = IS_VAR | | container ) {
2005-06-16 20:17:39 +08:00
if ( OP1_TYPE = = IS_CV & & container ! = & EG ( uninitialized_zval_ptr ) ) {
SEPARATE_ZVAL_IF_NOT_REF ( container ) ;
}
if ( Z_TYPE_PP ( container ) = = IS_OBJECT ) {
if ( IS_OP2_TMP_FREE ( ) ) {
MAKE_REAL_ZVAL_PTR ( offset ) ;
}
2008-07-26 22:08:11 +08:00
if ( Z_OBJ_HT_P ( * container ) - > unset_property ) {
2010-04-20 18:57:45 +08:00
Z_OBJ_HT_P ( * container ) - > unset_property ( * container , offset , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) TSRMLS_CC ) ;
2008-07-26 22:08:11 +08:00
} else {
zend_error ( E_NOTICE , " Trying to unset property of non-object " ) ;
}
2005-06-16 20:17:39 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
zval_ptr_dtor ( & offset ) ;
} else {
FREE_OP2 ( ) ;
2004-10-23 05:42:14 +08:00
}
2005-06-16 20:17:39 +08:00
} else {
FREE_OP2 ( ) ;
2004-10-23 05:42:14 +08:00
}
} else {
2005-06-03 19:16:19 +08:00
FREE_OP2 ( ) ;
2004-10-23 05:42:14 +08:00
}
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 77 , ZEND_FE_RESET , CONST | TMP | VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
zval * array_ptr , * * array_ptr_ptr ;
HashTable * fe_ht ;
zend_object_iterator * iter = NULL ;
zend_class_entry * ce = NULL ;
2005-02-05 22:01:59 +08:00
zend_bool is_empty = 0 ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-07-27 17:50:35 +08:00
if ( ( OP1_TYPE = = IS_CV | | OP1_TYPE = = IS_VAR ) & &
( opline - > extended_value & ZEND_FE_RESET_VARIABLE ) ) {
2004-10-23 05:42:14 +08:00
array_ptr_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_R ) ;
2005-08-05 14:29:46 +08:00
if ( array_ptr_ptr = = NULL | | array_ptr_ptr = = & EG ( uninitialized_zval_ptr ) ) {
2010-04-20 19:16:39 +08:00
MAKE_STD_ZVAL ( array_ptr ) ;
ZVAL_NULL ( array_ptr ) ;
2004-10-23 05:42:14 +08:00
} else if ( Z_TYPE_PP ( array_ptr_ptr ) = = IS_OBJECT ) {
2005-06-28 18:49:56 +08:00
if ( Z_OBJ_HT_PP ( array_ptr_ptr ) - > get_class_entry = = NULL ) {
2009-06-07 23:46:54 +08:00
zend_error ( E_WARNING , " foreach() cannot iterate over objects without PHP class " ) ;
2010-04-20 18:57:45 +08:00
ZEND_VM_JMP ( EX ( op_array ) - > opcodes + opline - > op2 . opline_num ) ;
2005-06-28 18:49:56 +08:00
}
2006-05-12 05:07:39 +08:00
2004-10-23 05:42:14 +08:00
ce = Z_OBJCE_PP ( array_ptr_ptr ) ;
if ( ! ce | | ce - > get_iterator = = NULL ) {
SEPARATE_ZVAL_IF_NOT_REF ( array_ptr_ptr ) ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_PP ( array_ptr_ptr ) ;
2004-10-23 05:42:14 +08:00
}
array_ptr = * array_ptr_ptr ;
} else {
2006-02-06 19:45:56 +08:00
if ( Z_TYPE_PP ( array_ptr_ptr ) = = IS_ARRAY ) {
SEPARATE_ZVAL_IF_NOT_REF ( array_ptr_ptr ) ;
2007-04-06 07:48:43 +08:00
if ( opline - > extended_value & ZEND_FE_FETCH_BYREF ) {
2007-10-07 13:22:07 +08:00
Z_SET_ISREF_PP ( array_ptr_ptr ) ;
2007-04-06 07:48:43 +08:00
}
2006-02-06 19:45:56 +08:00
}
2004-10-23 05:42:14 +08:00
array_ptr = * array_ptr_ptr ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( array_ptr ) ;
2004-10-23 05:42:14 +08:00
}
} else {
array_ptr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
if ( IS_OP1_TMP_FREE ( ) ) { /* IS_TMP_VAR */
zval * tmp ;
ALLOC_ZVAL ( tmp ) ;
INIT_PZVAL_COPY ( tmp , array_ptr ) ;
array_ptr = tmp ;
2009-08-17 15:40:43 +08:00
if ( Z_TYPE_P ( array_ptr ) = = IS_OBJECT ) {
ce = Z_OBJCE_P ( array_ptr ) ;
if ( ce & & ce - > get_iterator ) {
Z_DELREF_P ( array_ptr ) ;
}
}
2004-10-23 05:42:14 +08:00
} else if ( Z_TYPE_P ( array_ptr ) = = IS_OBJECT ) {
ce = Z_OBJCE_P ( array_ptr ) ;
2006-10-03 17:05:14 +08:00
if ( ! ce | | ! ce - > get_iterator ) {
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( array_ptr ) ;
2006-10-03 17:05:14 +08:00
}
2011-03-16 13:25:02 +08:00
} else if ( OP1_TYPE = = IS_CONST | |
2009-08-17 15:40:43 +08:00
( ( OP1_TYPE = = IS_CV | | OP1_TYPE = = IS_VAR ) & &
! Z_ISREF_P ( array_ptr ) & &
Z_REFCOUNT_P ( array_ptr ) > 1 ) ) {
zval * tmp ;
ALLOC_ZVAL ( tmp ) ;
INIT_PZVAL_COPY ( tmp , array_ptr ) ;
zval_copy_ctor ( tmp ) ;
array_ptr = tmp ;
2004-10-23 05:42:14 +08:00
} else {
2009-08-17 15:40:43 +08:00
Z_ADDREF_P ( array_ptr ) ;
2004-10-23 05:42:14 +08:00
}
}
2009-08-17 15:40:43 +08:00
if ( ce & & ce - > get_iterator ) {
2006-05-12 05:07:39 +08:00
iter = ce - > get_iterator ( ce , array_ptr , opline - > extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
if ( iter & & EXPECTED ( EG ( exception ) = = NULL ) ) {
2004-10-23 05:42:14 +08:00
array_ptr = zend_iterator_wrap ( iter TSRMLS_CC ) ;
} else {
2010-10-22 21:59:23 +08:00
FREE_OP1_IF_VAR ( ) ;
2005-01-25 18:40:51 +08:00
if ( ! EG ( exception ) ) {
zend_throw_exception_ex ( NULL , 0 TSRMLS_CC , " Object of type %s did not create an Iterator " , ce - > name ) ;
}
2005-01-25 04:02:55 +08:00
zend_throw_exception_internal ( NULL TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
HANDLE_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
}
2010-10-22 22:51:07 +08:00
EX_T ( opline - > result . var ) . fe . ptr = array_ptr ;
2004-10-23 05:42:14 +08:00
if ( iter ) {
iter - > index = 0 ;
if ( iter - > funcs - > rewind ) {
iter - > funcs - > rewind ( iter TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2005-04-27 14:47:08 +08:00
zval_ptr_dtor ( & array_ptr ) ;
2010-10-22 21:59:23 +08:00
FREE_OP1_IF_VAR ( ) ;
2010-04-20 19:16:39 +08:00
HANDLE_EXCEPTION ( ) ;
2005-04-27 14:47:08 +08:00
}
2004-10-23 05:42:14 +08:00
}
2005-02-05 22:01:59 +08:00
is_empty = iter - > funcs - > valid ( iter TSRMLS_CC ) ! = SUCCESS ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2005-04-27 14:47:08 +08:00
zval_ptr_dtor ( & array_ptr ) ;
2010-10-22 21:59:23 +08:00
FREE_OP1_IF_VAR ( ) ;
2010-04-20 19:16:39 +08:00
HANDLE_EXCEPTION ( ) ;
2005-04-27 14:47:08 +08:00
}
2006-05-12 05:07:39 +08:00
iter - > index = - 1 ; /* will be set to 0 before using next handler */
2004-10-23 05:42:14 +08:00
} else if ( ( fe_ht = HASH_OF ( array_ptr ) ) ! = NULL ) {
zend_hash_internal_pointer_reset ( fe_ht ) ;
2005-02-05 22:01:59 +08:00
if ( ce ) {
zend_object * zobj = zend_objects_get_address ( array_ptr TSRMLS_CC ) ;
while ( zend_hash_has_more_elements ( fe_ht ) = = SUCCESS ) {
char * str_key ;
uint str_key_len ;
ulong int_key ;
2006-05-12 05:07:39 +08:00
zend_uchar key_type ;
key_type = zend_hash_get_current_key_ex ( fe_ht , & str_key , & str_key_len , & int_key , 0 , NULL ) ;
if ( key_type ! = HASH_KEY_NON_EXISTANT & &
2006-12-26 03:23:03 +08:00
( key_type = = HASH_KEY_IS_LONG | |
zend_check_property_access ( zobj , str_key , str_key_len - 1 TSRMLS_CC ) = = SUCCESS ) ) {
2005-02-05 22:01:59 +08:00
break ;
}
zend_hash_move_forward ( fe_ht ) ;
}
}
is_empty = zend_hash_has_more_elements ( fe_ht ) ! = SUCCESS ;
2010-04-20 18:57:45 +08:00
zend_hash_get_pointer ( fe_ht , & EX_T ( opline - > result . var ) . fe . fe_pos ) ;
2004-10-23 05:42:14 +08:00
} else {
zend_error ( E_WARNING , " Invalid argument supplied for foreach() " ) ;
2005-02-05 22:01:59 +08:00
is_empty = 1 ;
2004-10-23 05:42:14 +08:00
}
2010-10-22 21:59:23 +08:00
FREE_OP1_IF_VAR ( ) ;
2005-02-05 22:01:59 +08:00
if ( is_empty ) {
2010-04-20 18:57:45 +08:00
ZEND_VM_JMP ( EX ( op_array ) - > opcodes + opline - > op2 . opline_num ) ;
2005-02-05 22:01:59 +08:00
} else {
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2005-02-05 22:01:59 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
}
ZEND_VM_HANDLER ( 78 , ZEND_FE_FETCH , VAR , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-10-22 22:51:07 +08:00
zval * array = EX_T ( opline - > op1 . var ) . fe . ptr ;
2005-02-08 00:09:54 +08:00
zval * * value ;
2004-10-23 05:42:14 +08:00
char * str_key ;
uint str_key_len ;
ulong int_key ;
HashTable * fe_ht ;
zend_object_iterator * iter = NULL ;
2006-07-13 05:17:30 +08:00
int key_type = 0 ;
2006-02-26 18:57:00 +08:00
zend_bool use_key = ( zend_bool ) ( opline - > extended_value & ZEND_FE_FETCH_WITH_KEY ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
switch ( zend_iterator_unwrap ( array , & iter TSRMLS_CC ) ) {
default :
case ZEND_ITER_INVALID :
zend_error ( E_WARNING , " Invalid argument supplied for foreach() " ) ;
2010-04-20 18:57:45 +08:00
ZEND_VM_JMP ( EX ( op_array ) - > opcodes + opline - > op2 . opline_num ) ;
2004-10-23 05:42:14 +08:00
case ZEND_ITER_PLAIN_OBJECT : {
2011-09-13 21:29:35 +08:00
const char * class_name , * prop_name ;
2004-10-23 05:42:14 +08:00
zend_object * zobj = zend_objects_get_address ( array TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
fe_ht = Z_OBJPROP_P ( array ) ;
2010-04-20 18:57:45 +08:00
zend_hash_set_pointer ( fe_ht , & EX_T ( opline - > op1 . var ) . fe . fe_pos ) ;
2004-10-23 05:42:14 +08:00
do {
if ( zend_hash_get_current_data ( fe_ht , ( void * * ) & value ) = = FAILURE ) {
/* reached end of iteration */
2010-04-20 18:57:45 +08:00
ZEND_VM_JMP ( EX ( op_array ) - > opcodes + opline - > op2 . opline_num ) ;
2004-10-23 05:42:14 +08:00
}
key_type = zend_hash_get_current_key_ex ( fe_ht , & str_key , & str_key_len , & int_key , 0 , NULL ) ;
zend_hash_move_forward ( fe_ht ) ;
2006-12-26 03:23:03 +08:00
} while ( key_type = = HASH_KEY_NON_EXISTANT | |
( key_type ! = HASH_KEY_IS_LONG & &
zend_check_property_access ( zobj , str_key , str_key_len - 1 TSRMLS_CC ) ! = SUCCESS ) ) ;
2010-04-20 18:57:45 +08:00
zend_hash_get_pointer ( fe_ht , & EX_T ( opline - > op1 . var ) . fe . fe_pos ) ;
2006-12-26 03:23:03 +08:00
if ( use_key & & key_type ! = HASH_KEY_IS_LONG ) {
2006-07-25 01:58:32 +08:00
zend_unmangle_property_name ( str_key , str_key_len - 1 , & class_name , & prop_name ) ;
2004-10-23 05:42:14 +08:00
str_key_len = strlen ( prop_name ) ;
str_key = estrndup ( prop_name , str_key_len ) ;
str_key_len + + ;
}
break ;
}
case ZEND_ITER_PLAIN_ARRAY :
2010-04-20 19:16:39 +08:00
fe_ht = Z_ARRVAL_P ( array ) ;
2010-04-20 18:57:45 +08:00
zend_hash_set_pointer ( fe_ht , & EX_T ( opline - > op1 . var ) . fe . fe_pos ) ;
2004-10-23 05:42:14 +08:00
if ( zend_hash_get_current_data ( fe_ht , ( void * * ) & value ) = = FAILURE ) {
/* reached end of iteration */
2010-04-20 18:57:45 +08:00
ZEND_VM_JMP ( EX ( op_array ) - > opcodes + opline - > op2 . opline_num ) ;
2004-10-23 05:42:14 +08:00
}
if ( use_key ) {
key_type = zend_hash_get_current_key_ex ( fe_ht , & str_key , & str_key_len , & int_key , 1 , NULL ) ;
}
zend_hash_move_forward ( fe_ht ) ;
2010-04-20 18:57:45 +08:00
zend_hash_get_pointer ( fe_ht , & EX_T ( opline - > op1 . var ) . fe . fe_pos ) ;
2004-10-23 05:42:14 +08:00
break ;
case ZEND_ITER_OBJECT :
/* !iter happens from exception */
2006-05-12 05:07:39 +08:00
if ( iter & & + + iter - > index > 0 ) {
2004-10-23 05:42:14 +08:00
/* This could cause an endless loop if index becomes zero again.
* In case that ever happens we need an additional flag . */
iter - > funcs - > move_forward ( iter TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2005-04-27 14:47:08 +08:00
zval_ptr_dtor ( & array ) ;
2010-04-20 19:16:39 +08:00
HANDLE_EXCEPTION ( ) ;
2005-04-27 14:47:08 +08:00
}
2004-10-23 05:42:14 +08:00
}
2006-05-12 05:07:39 +08:00
/* If index is zero we come from FE_RESET and checked valid() already. */
if ( ! iter | | ( iter - > index > 0 & & iter - > funcs - > valid ( iter TSRMLS_CC ) = = FAILURE ) ) {
2004-10-23 05:42:14 +08:00
/* reached end of iteration */
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2005-04-27 14:47:08 +08:00
zval_ptr_dtor ( & array ) ;
2010-04-20 19:16:39 +08:00
HANDLE_EXCEPTION ( ) ;
2005-04-27 14:47:08 +08:00
}
2010-04-20 18:57:45 +08:00
ZEND_VM_JMP ( EX ( op_array ) - > opcodes + opline - > op2 . opline_num ) ;
2004-10-23 05:42:14 +08:00
}
iter - > funcs - > get_current_data ( iter , & value TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2005-06-06 16:24:05 +08:00
zval_ptr_dtor ( & array ) ;
2010-04-20 19:16:39 +08:00
HANDLE_EXCEPTION ( ) ;
2005-06-06 16:24:05 +08:00
}
2004-10-23 05:42:14 +08:00
if ( ! value ) {
/* failure in get_current_data */
2010-04-20 18:57:45 +08:00
ZEND_VM_JMP ( EX ( op_array ) - > opcodes + opline - > op2 . opline_num ) ;
2004-10-23 05:42:14 +08:00
}
if ( use_key ) {
if ( iter - > funcs - > get_current_key ) {
key_type = iter - > funcs - > get_current_key ( iter , & str_key , & str_key_len , & int_key TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2005-04-27 14:47:08 +08:00
zval_ptr_dtor ( & array ) ;
2010-04-20 19:16:39 +08:00
HANDLE_EXCEPTION ( ) ;
2005-04-27 14:47:08 +08:00
}
2004-10-23 05:42:14 +08:00
} else {
key_type = HASH_KEY_IS_LONG ;
int_key = iter - > index ;
}
}
break ;
}
if ( opline - > extended_value & ZEND_FE_FETCH_BYREF ) {
SEPARATE_ZVAL_IF_NOT_REF ( value ) ;
2007-10-07 13:22:07 +08:00
Z_SET_ISREF_PP ( value ) ;
2010-04-20 18:57:45 +08:00
EX_T ( opline - > result . var ) . var . ptr_ptr = value ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_PP ( value ) ;
2005-02-08 00:09:54 +08:00
} else {
2007-12-14 22:14:50 +08:00
PZVAL_LOCK ( * value ) ;
2010-04-20 19:16:39 +08:00
AI_SET_PTR ( & EX_T ( opline - > result . var ) , * value ) ;
2005-02-08 00:09:54 +08:00
}
2004-10-23 05:42:14 +08:00
2005-02-08 00:09:54 +08:00
if ( use_key ) {
2010-04-20 19:16:39 +08:00
zval * key = & EX_T ( ( opline + 1 ) - > result . var ) . tmp_var ;
2004-10-23 05:42:14 +08:00
switch ( key_type ) {
case HASH_KEY_IS_STRING :
2011-09-13 21:29:35 +08:00
Z_STRVAL_P ( key ) = ( char * ) str_key ;
2006-05-12 05:07:39 +08:00
Z_STRLEN_P ( key ) = str_key_len - 1 ;
Z_TYPE_P ( key ) = IS_STRING ;
2004-10-23 05:42:14 +08:00
break ;
case HASH_KEY_IS_LONG :
2006-05-12 05:07:39 +08:00
Z_LVAL_P ( key ) = int_key ;
Z_TYPE_P ( key ) = IS_LONG ;
2004-10-23 05:42:14 +08:00
break ;
2006-04-11 07:16:29 +08:00
default :
2006-05-12 05:07:39 +08:00
case HASH_KEY_NON_EXISTANT :
2006-04-11 07:16:29 +08:00
ZVAL_NULL ( key ) ;
break ;
2004-10-23 05:42:14 +08:00
}
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2005-02-08 00:09:54 +08:00
ZEND_VM_INC_OPCODE ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2010-05-06 18:27:35 +08:00
ZEND_VM_HANDLER ( 114 , ZEND_ISSET_ISEMPTY_VAR , CONST | TMP | VAR | CV , UNUSED | CONST | VAR )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zval * * value ;
zend_bool isset = 1 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-07-27 17:50:35 +08:00
if ( OP1_TYPE = = IS_CV & &
OP2_TYPE = = IS_UNUSED & &
( opline - > extended_value & ZEND_QUICK_SET ) ) {
2010-04-20 19:16:39 +08:00
if ( EX_CV ( opline - > op1 . var ) ) {
value = EX_CV ( opline - > op1 . var ) ;
2008-04-29 16:15:20 +08:00
} else if ( EG ( active_symbol_table ) ) {
2010-04-20 18:57:45 +08:00
zend_compiled_variable * cv = & CV_DEF_OF ( opline - > op1 . var ) ;
2004-10-23 05:42:14 +08:00
2008-04-29 16:15:20 +08:00
if ( zend_hash_quick_find ( EG ( active_symbol_table ) , cv - > name , cv - > name_len + 1 , cv - > hash_value , ( void * * ) & value ) = = FAILURE ) {
isset = 0 ;
}
2011-03-16 13:25:02 +08:00
} else {
2004-10-23 05:42:14 +08:00
isset = 0 ;
}
} else {
2008-04-29 16:15:20 +08:00
HashTable * target_symbol_table ;
zend_free_op free_op1 ;
zval tmp , * varname = GET_OP1_ZVAL_PTR ( BP_VAR_IS ) ;
2010-04-20 18:57:45 +08:00
if ( OP1_TYPE ! = IS_CONST & & Z_TYPE_P ( varname ) ! = IS_STRING ) {
2010-04-20 19:16:39 +08:00
ZVAL_COPY_VALUE ( & tmp , varname ) ;
2008-04-29 16:15:20 +08:00
zval_copy_ctor ( & tmp ) ;
convert_to_string ( & tmp ) ;
varname = & tmp ;
2004-10-23 05:42:14 +08:00
}
2008-04-29 16:15:20 +08:00
2010-05-06 18:27:35 +08:00
if ( OP2_TYPE ! = IS_UNUSED ) {
zend_class_entry * ce ;
if ( OP2_TYPE = = IS_CONST ) {
2010-05-24 22:11:39 +08:00
if ( CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ) {
ce = CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ;
} else {
ce = zend_fetch_class_by_name ( Z_STRVAL_P ( opline - > op2 . zv ) , Z_STRLEN_P ( opline - > op2 . zv ) , opline - > op2 . literal + 1 , 0 TSRMLS_CC ) ;
2012-02-25 21:56:59 +08:00
if ( UNEXPECTED ( ce = = NULL ) ) {
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2010-05-24 22:11:39 +08:00
CACHE_PTR ( opline - > op2 . literal - > cache_slot , ce ) ;
}
2010-05-06 18:27:35 +08:00
} else {
ce = EX_T ( opline - > op2 . var ) . class_entry ;
}
value = zend_std_get_static_property ( ce , Z_STRVAL_P ( varname ) , Z_STRLEN_P ( varname ) , 1 , ( ( OP1_TYPE = = IS_CONST ) ? opline - > op1 . literal : NULL ) TSRMLS_CC ) ;
2008-04-29 16:15:20 +08:00
if ( ! value ) {
isset = 0 ;
}
} else {
2010-04-20 18:57:45 +08:00
target_symbol_table = zend_get_target_symbol_table ( opline - > extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC ) ;
2008-04-29 16:15:20 +08:00
if ( zend_hash_find ( target_symbol_table , varname - > value . str . val , varname - > value . str . len + 1 , ( void * * ) & value ) = = FAILURE ) {
isset = 0 ;
}
}
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE ! = IS_CONST & & varname = = & tmp ) {
2008-04-29 16:15:20 +08:00
zval_dtor ( & tmp ) ;
}
FREE_OP1 ( ) ;
2004-10-23 05:42:14 +08:00
}
2010-04-20 18:57:45 +08:00
if ( opline - > extended_value & ZEND_ISSET ) {
2010-04-20 19:16:39 +08:00
if ( isset & & Z_TYPE_PP ( value ) ! = IS_NULL ) {
ZVAL_BOOL ( & EX_T ( opline - > result . var ) . tmp_var , 1 ) ;
2010-04-20 18:57:45 +08:00
} else {
2010-04-20 19:16:39 +08:00
ZVAL_BOOL ( & EX_T ( opline - > result . var ) . tmp_var , 0 ) ;
2010-04-20 18:57:45 +08:00
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
if ( ! isset | | ! i_zend_is_true ( * value ) ) {
2010-04-20 19:16:39 +08:00
ZVAL_BOOL ( & EX_T ( opline - > result . var ) . tmp_var , 1 ) ;
2010-04-20 18:57:45 +08:00
} else {
2010-04-20 19:16:39 +08:00
ZVAL_BOOL ( & EX_T ( opline - > result . var ) . tmp_var , 0 ) ;
2010-04-20 18:57:45 +08:00
}
2004-10-23 05:42:14 +08:00
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HELPER_EX ( zend_isset_isempty_dim_prop_obj_handler , VAR | UNUSED | CV , CONST | TMP | VAR | CV , int prop_dim )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2010-07-16 19:44:30 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
zval * * container ;
2004-10-23 05:42:14 +08:00
zval * * value = NULL ;
int result = 0 ;
2010-04-20 18:57:45 +08:00
ulong hval ;
2010-07-16 19:44:30 +08:00
zval * offset ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
container = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_IS ) ;
2011-03-16 13:25:02 +08:00
2010-07-16 19:44:30 +08:00
offset = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2005-06-03 19:16:19 +08:00
2010-07-16 19:44:30 +08:00
if ( Z_TYPE_PP ( container ) = = IS_ARRAY & & ! prop_dim ) {
HashTable * ht ;
int isset = 0 ;
2004-10-23 05:42:14 +08:00
2010-07-16 19:44:30 +08:00
ht = Z_ARRVAL_PP ( container ) ;
2004-10-23 05:42:14 +08:00
2010-07-16 19:44:30 +08:00
switch ( Z_TYPE_P ( offset ) ) {
case IS_DOUBLE :
2010-10-05 19:28:56 +08:00
hval = zend_dval_to_lval ( Z_DVAL_P ( offset ) ) ;
2010-07-16 19:44:30 +08:00
ZEND_VM_C_GOTO ( num_index_prop ) ;
case IS_RESOURCE :
case IS_BOOL :
case IS_LONG :
2010-10-05 19:28:56 +08:00
hval = Z_LVAL_P ( offset ) ;
2010-04-20 18:57:45 +08:00
ZEND_VM_C_LABEL ( num_index_prop ) :
2010-10-05 19:28:56 +08:00
if ( zend_hash_index_find ( ht , hval , ( void * * ) & value ) = = SUCCESS ) {
2010-07-16 19:44:30 +08:00
isset = 1 ;
}
break ;
case IS_STRING :
if ( OP2_TYPE = = IS_CONST ) {
hval = Z_HASH_P ( offset ) ;
} else {
if ( ! prop_dim ) {
2010-10-05 19:28:56 +08:00
ZEND_HANDLE_NUMERIC_EX ( Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 , hval , ZEND_VM_C_GOTO ( num_index_prop ) ) ;
2004-10-23 05:42:14 +08:00
}
2010-07-16 19:44:30 +08:00
if ( IS_INTERNED ( Z_STRVAL_P ( offset ) ) ) {
hval = INTERNED_HASH ( Z_STRVAL_P ( offset ) ) ;
2010-04-20 18:57:45 +08:00
} else {
2010-07-16 19:44:30 +08:00
hval = zend_hash_func ( Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 ) ;
2004-10-23 05:42:14 +08:00
}
2010-04-20 18:57:45 +08:00
}
2010-07-16 19:44:30 +08:00
if ( zend_hash_quick_find ( ht , Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 , hval , ( void * * ) & value ) = = SUCCESS ) {
isset = 1 ;
2010-04-20 18:57:45 +08:00
}
2010-07-16 19:44:30 +08:00
break ;
case IS_NULL :
if ( zend_hash_find ( ht , " " , sizeof ( " " ) , ( void * * ) & value ) = = SUCCESS ) {
isset = 1 ;
2008-07-26 22:08:11 +08:00
}
2010-07-16 19:44:30 +08:00
break ;
default :
zend_error ( E_WARNING , " Illegal offset type in isset or empty " ) ;
break ;
}
if ( opline - > extended_value & ZEND_ISSET ) {
if ( isset & & Z_TYPE_PP ( value ) = = IS_NULL ) {
result = 0 ;
2004-10-23 05:42:14 +08:00
} else {
2010-07-16 19:44:30 +08:00
result = isset ;
2004-10-23 05:42:14 +08:00
}
2010-07-16 19:44:30 +08:00
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
if ( ! isset | | ! i_zend_is_true ( * value ) ) {
result = 0 ;
2005-06-03 19:16:19 +08:00
} else {
2010-07-16 19:44:30 +08:00
result = 1 ;
2005-06-03 19:16:19 +08:00
}
2010-07-16 19:44:30 +08:00
}
FREE_OP2 ( ) ;
} else if ( Z_TYPE_PP ( container ) = = IS_OBJECT ) {
if ( IS_OP2_TMP_FREE ( ) ) {
MAKE_REAL_ZVAL_PTR ( offset ) ;
}
if ( prop_dim ) {
if ( Z_OBJ_HT_P ( * container ) - > has_property ) {
result = Z_OBJ_HT_P ( * container ) - > has_property ( * container , offset , ( opline - > extended_value & ZEND_ISEMPTY ) ! = 0 , ( ( OP2_TYPE = = IS_CONST ) ? opline - > op2 . literal : NULL ) TSRMLS_CC ) ;
} else {
zend_error ( E_NOTICE , " Trying to check property of non-object " ) ;
result = 0 ;
2004-12-01 22:02:35 +08:00
}
2010-07-16 19:44:30 +08:00
} else {
if ( Z_OBJ_HT_P ( * container ) - > has_dimension ) {
result = Z_OBJ_HT_P ( * container ) - > has_dimension ( * container , offset , ( opline - > extended_value & ZEND_ISEMPTY ) ! = 0 TSRMLS_CC ) ;
} else {
zend_error ( E_NOTICE , " Trying to check element of non-array " ) ;
result = 0 ;
2004-10-23 05:42:14 +08:00
}
2010-07-16 19:44:30 +08:00
}
if ( IS_OP2_TMP_FREE ( ) ) {
zval_ptr_dtor ( & offset ) ;
2005-06-03 19:16:19 +08:00
} else {
FREE_OP2 ( ) ;
2004-10-23 05:42:14 +08:00
}
2010-07-16 19:44:30 +08:00
} else if ( ( * container ) - > type = = IS_STRING & & ! prop_dim ) { /* string offsets */
zval tmp ;
if ( Z_TYPE_P ( offset ) ! = IS_LONG ) {
2011-12-19 10:05:03 +08:00
if ( Z_TYPE_P ( offset ) < = IS_BOOL /* simple scalar types */
2012-01-26 09:28:37 +08:00
| | ( Z_TYPE_P ( offset ) = = IS_STRING /* or numeric string */
2011-12-22 11:22:42 +08:00
& & IS_LONG = = is_numeric_string ( Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) , NULL , NULL , 0 ) ) ) {
2012-01-26 09:28:37 +08:00
ZVAL_COPY_VALUE ( & tmp , offset ) ;
zval_copy_ctor ( & tmp ) ;
convert_to_long ( & tmp ) ;
offset = & tmp ;
2011-12-19 10:05:03 +08:00
} else {
/* can not be converted to proper offset, return "not set" */
result = 0 ;
2012-01-26 09:28:37 +08:00
}
2010-07-16 19:44:30 +08:00
}
if ( Z_TYPE_P ( offset ) = = IS_LONG ) {
if ( opline - > extended_value & ZEND_ISSET ) {
if ( offset - > value . lval > = 0 & & offset - > value . lval < Z_STRLEN_PP ( container ) ) {
result = 1 ;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
if ( offset - > value . lval > = 0 & & offset - > value . lval < Z_STRLEN_PP ( container ) & & Z_STRVAL_PP ( container ) [ offset - > value . lval ] ! = ' 0 ' ) {
result = 1 ;
}
}
}
FREE_OP2 ( ) ;
} else {
FREE_OP2 ( ) ;
2004-10-23 05:42:14 +08:00
}
2010-04-20 18:57:45 +08:00
Z_TYPE ( EX_T ( opline - > result . var ) . tmp_var ) = IS_BOOL ;
if ( opline - > extended_value & ZEND_ISSET ) {
Z_LVAL ( EX_T ( opline - > result . var ) . tmp_var ) = result ;
2010-04-20 19:16:39 +08:00
} else {
2010-04-20 18:57:45 +08:00
Z_LVAL ( EX_T ( opline - > result . var ) . tmp_var ) = ! result ;
2004-10-23 05:42:14 +08:00
}
FREE_OP1_VAR_PTR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 115 , ZEND_ISSET_ISEMPTY_DIM_OBJ , VAR | UNUSED | CV , CONST | TMP | VAR | CV )
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_isset_isempty_dim_prop_obj_handler , prop_dim , 0 ) ;
}
ZEND_VM_HANDLER ( 148 , ZEND_ISSET_ISEMPTY_PROP_OBJ , VAR | UNUSED | CV , CONST | TMP | VAR | CV )
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_isset_isempty_dim_prop_obj_handler , prop_dim , 1 ) ;
}
ZEND_VM_HANDLER ( 79 , ZEND_EXIT , CONST | TMP | VAR | UNUSED | CV , ANY )
{
2006-06-08 16:37:51 +08:00
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
2010-04-20 19:16:39 +08:00
USE_OPLINE
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
if ( OP1_TYPE ! = IS_UNUSED ) {
zend_free_op free_op1 ;
2005-06-16 22:20:00 +08:00
zval * ptr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
if ( Z_TYPE_P ( ptr ) = = IS_LONG ) {
EG ( exit_status ) = Z_LVAL_P ( ptr ) ;
} else {
zend_print_variable ( ptr ) ;
}
FREE_OP1 ( ) ;
}
2006-05-22 02:00:14 +08:00
# endif
2004-10-23 05:42:14 +08:00
zend_bailout ( ) ;
2010-04-20 19:16:39 +08:00
ZEND_VM_NEXT_OPCODE ( ) ; /* Never reached */
2004-10-23 05:42:14 +08:00
}
ZEND_VM_HANDLER ( 57 , ZEND_BEGIN_SILENCE , ANY , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2006-05-12 05:07:39 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
Z_LVAL ( EX_T ( opline - > result . var ) . tmp_var ) = EG ( error_reporting ) ;
Z_TYPE ( EX_T ( opline - > result . var ) . tmp_var ) = IS_LONG ; /* shouldn't be necessary */
2005-09-23 17:36:43 +08:00
if ( EX ( old_error_reporting ) = = NULL ) {
2010-04-20 18:57:45 +08:00
EX ( old_error_reporting ) = & EX_T ( opline - > result . var ) . tmp_var ;
2005-09-23 17:36:43 +08:00
}
2006-05-12 05:07:39 +08:00
2005-09-23 03:03:18 +08:00
if ( EG ( error_reporting ) ) {
2010-08-18 21:58:13 +08:00
do {
EG ( error_reporting ) = 0 ;
if ( ! EG ( error_reporting_ini_entry ) ) {
if ( UNEXPECTED ( zend_hash_find ( EG ( ini_directives ) , " error_reporting " , sizeof ( " error_reporting " ) , ( void * * ) & EG ( error_reporting_ini_entry ) ) = = FAILURE ) ) {
break ;
}
}
if ( ! EG ( error_reporting_ini_entry ) - > modified ) {
if ( ! EG ( modified_ini_directives ) ) {
ALLOC_HASHTABLE ( EG ( modified_ini_directives ) ) ;
zend_hash_init ( EG ( modified_ini_directives ) , 8 , NULL , NULL , 0 ) ;
}
if ( EXPECTED ( zend_hash_add ( EG ( modified_ini_directives ) , " error_reporting " , sizeof ( " error_reporting " ) , & EG ( error_reporting_ini_entry ) , sizeof ( zend_ini_entry * ) , NULL ) = = SUCCESS ) ) {
EG ( error_reporting_ini_entry ) - > orig_value = EG ( error_reporting_ini_entry ) - > value ;
EG ( error_reporting_ini_entry ) - > orig_value_length = EG ( error_reporting_ini_entry ) - > value_length ;
EG ( error_reporting_ini_entry ) - > orig_modifiable = EG ( error_reporting_ini_entry ) - > modifiable ;
EG ( error_reporting_ini_entry ) - > modified = 1 ;
}
} else if ( EG ( error_reporting_ini_entry ) - > value ! = EG ( error_reporting_ini_entry ) - > orig_value ) {
efree ( EG ( error_reporting_ini_entry ) - > value ) ;
}
EG ( error_reporting_ini_entry ) - > value = estrndup ( " 0 " , sizeof ( " 0 " ) - 1 ) ;
EG ( error_reporting_ini_entry ) - > value_length = sizeof ( " 0 " ) - 1 ;
} while ( 0 ) ;
2005-09-23 03:03:18 +08:00
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 142 , ZEND_RAISE_ABSTRACT_ERROR , ANY , ANY )
{
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Cannot call abstract method %s::%s() " , EG ( scope ) - > name , EX ( op_array ) - > function_name ) ;
ZEND_VM_NEXT_OPCODE ( ) ; /* Never reached */
}
ZEND_VM_HANDLER ( 58 , ZEND_END_SILENCE , TMP , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zval restored_error_reporting ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
if ( ! EG ( error_reporting ) & & Z_LVAL ( EX_T ( opline - > op1 . var ) . tmp_var ) ! = 0 ) {
2006-05-12 05:07:39 +08:00
Z_TYPE ( restored_error_reporting ) = IS_LONG ;
2010-04-20 18:57:45 +08:00
Z_LVAL ( restored_error_reporting ) = Z_LVAL ( EX_T ( opline - > op1 . var ) . tmp_var ) ;
2010-08-18 21:58:13 +08:00
EG ( error_reporting ) = Z_LVAL ( restored_error_reporting ) ;
2004-10-23 05:42:14 +08:00
convert_to_string ( & restored_error_reporting ) ;
2010-08-18 21:58:13 +08:00
if ( EXPECTED ( EG ( error_reporting_ini_entry ) ! = NULL ) ) {
if ( EXPECTED ( EG ( error_reporting_ini_entry ) - > modified & &
EG ( error_reporting_ini_entry ) - > value ! = EG ( error_reporting_ini_entry ) - > orig_value ) ) {
efree ( EG ( error_reporting_ini_entry ) - > value ) ;
}
EG ( error_reporting_ini_entry ) - > value = Z_STRVAL ( restored_error_reporting ) ;
EG ( error_reporting_ini_entry ) - > value_length = Z_STRLEN ( restored_error_reporting ) ;
} else {
zendi_zval_dtor ( restored_error_reporting ) ;
}
2004-10-23 05:42:14 +08:00
}
2010-04-20 18:57:45 +08:00
if ( EX ( old_error_reporting ) = = & EX_T ( opline - > op1 . var ) . tmp_var ) {
2005-09-23 17:36:43 +08:00
EX ( old_error_reporting ) = NULL ;
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2007-11-21 17:41:35 +08:00
ZEND_VM_HANDLER ( 152 , ZEND_JMP_SET , CONST | TMP | VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2007-11-21 17:41:35 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
zval * value ;
SAVE_OPLINE ( ) ;
value = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2007-11-21 17:41:35 +08:00
if ( i_zend_is_true ( value ) ) {
2010-04-20 19:16:39 +08:00
ZVAL_COPY_VALUE ( & EX_T ( opline - > result . var ) . tmp_var , value ) ;
2011-10-19 03:42:42 +08:00
if ( ! IS_OP1_TMP_FREE ( ) ) {
zendi_zval_copy_ctor ( EX_T ( opline - > result . var ) . tmp_var ) ;
}
FREE_OP1_IF_VAR ( ) ;
# if DEBUG_ZEND>=2
printf ( " Conditional jmp to %d \n " , opline - > op2 . opline_num ) ;
# endif
ZEND_VM_JMP ( opline - > op2 . jmp_addr ) ;
}
FREE_OP1 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 158 , ZEND_JMP_SET_VAR , CONST | TMP | VAR | CV , ANY )
{
USE_OPLINE
zend_free_op free_op1 ;
zval * value , * ret ;
SAVE_OPLINE ( ) ;
value = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
if ( i_zend_is_true ( value ) ) {
if ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) {
Z_ADDREF_P ( value ) ;
EX_T ( opline - > result . var ) . var . ptr = value ;
2011-11-03 11:59:41 +08:00
EX_T ( opline - > result . var ) . var . ptr_ptr = & EX_T ( opline - > result . var ) . var . ptr ;
2011-10-19 03:42:42 +08:00
} else {
ALLOC_ZVAL ( ret ) ;
INIT_PZVAL_COPY ( ret , value ) ;
EX_T ( opline - > result . var ) . var . ptr = ret ;
2011-11-03 11:59:41 +08:00
EX_T ( opline - > result . var ) . var . ptr_ptr = & EX_T ( opline - > result . var ) . var . ptr ;
2011-10-19 03:42:42 +08:00
if ( ! IS_OP1_TMP_FREE ( ) ) {
zval_copy_ctor ( EX_T ( opline - > result . var ) . var . ptr ) ;
}
}
FREE_OP1_IF_VAR ( ) ;
2007-11-21 17:41:35 +08:00
# if DEBUG_ZEND>=2
2010-04-20 18:57:45 +08:00
printf ( " Conditional jmp to %d \n " , opline - > op2 . opline_num ) ;
2007-11-21 17:41:35 +08:00
# endif
2010-04-20 18:57:45 +08:00
ZEND_VM_JMP ( opline - > op2 . jmp_addr ) ;
2007-11-21 17:41:35 +08:00
}
FREE_OP1 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2007-11-21 17:41:35 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
ZEND_VM_HANDLER ( 22 , ZEND_QM_ASSIGN , CONST | TMP | VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
zval * value ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
value = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
ZVAL_COPY_VALUE ( & EX_T ( opline - > result . var ) . tmp_var , value ) ;
2004-10-23 05:42:14 +08:00
if ( ! IS_OP1_TMP_FREE ( ) ) {
2010-04-20 18:57:45 +08:00
zval_copy_ctor ( & EX_T ( opline - > result . var ) . tmp_var ) ;
2004-10-23 05:42:14 +08:00
}
FREE_OP1_IF_VAR ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2011-10-19 03:42:42 +08:00
ZEND_VM_HANDLER ( 157 , ZEND_QM_ASSIGN_VAR , CONST | TMP | VAR | CV , ANY )
{
USE_OPLINE
zend_free_op free_op1 ;
zval * value , * ret ;
SAVE_OPLINE ( ) ;
value = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
if ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) {
Z_ADDREF_P ( value ) ;
EX_T ( opline - > result . var ) . var . ptr = value ;
2011-11-03 11:59:41 +08:00
EX_T ( opline - > result . var ) . var . ptr_ptr = & EX_T ( opline - > result . var ) . var . ptr ;
2011-10-19 03:42:42 +08:00
} else {
ALLOC_ZVAL ( ret ) ;
INIT_PZVAL_COPY ( ret , value ) ;
EX_T ( opline - > result . var ) . var . ptr = ret ;
2011-11-03 11:59:41 +08:00
EX_T ( opline - > result . var ) . var . ptr_ptr = & EX_T ( opline - > result . var ) . var . ptr ;
2011-10-19 03:42:42 +08:00
if ( ! IS_OP1_TMP_FREE ( ) ) {
zval_copy_ctor ( EX_T ( opline - > result . var ) . var . ptr ) ;
}
}
FREE_OP1_IF_VAR ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
ZEND_VM_HANDLER ( 101 , ZEND_EXT_STMT , ANY , ANY )
{
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
if ( ! EG ( no_extensions ) ) {
zend_llist_apply_with_argument ( & zend_extensions , ( llist_apply_with_arg_func_t ) zend_extension_statement_handler , EX ( op_array ) TSRMLS_CC ) ;
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 102 , ZEND_EXT_FCALL_BEGIN , ANY , ANY )
{
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
if ( ! EG ( no_extensions ) ) {
zend_llist_apply_with_argument ( & zend_extensions , ( llist_apply_with_arg_func_t ) zend_extension_fcall_begin_handler , EX ( op_array ) TSRMLS_CC ) ;
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 103 , ZEND_EXT_FCALL_END , ANY , ANY )
{
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
if ( ! EG ( no_extensions ) ) {
zend_llist_apply_with_argument ( & zend_extensions , ( llist_apply_with_arg_func_t ) zend_extension_fcall_end_handler , EX ( op_array ) TSRMLS_CC ) ;
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 139 , ZEND_DECLARE_CLASS , ANY , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
EX_T ( opline - > result . var ) . class_entry = do_bind_class ( EX ( op_array ) , opline , EG ( class_table ) , 0 TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 140 , ZEND_DECLARE_INHERITED_CLASS , ANY , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
EX_T ( opline - > result . var ) . class_entry = do_bind_inherited_class ( EX ( op_array ) , opline , EG ( class_table ) , EX_T ( opline - > extended_value ) . class_entry , 0 TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2008-03-18 16:36:30 +08:00
ZEND_VM_HANDLER ( 145 , ZEND_DECLARE_INHERITED_CLASS_DELAYED , ANY , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2008-03-18 16:36:30 +08:00
zend_class_entry * * pce , * * pce_orig ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
if ( zend_hash_quick_find ( EG ( class_table ) , Z_STRVAL_P ( opline - > op2 . zv ) , Z_STRLEN_P ( opline - > op2 . zv ) + 1 , Z_HASH_P ( opline - > op2 . zv ) , ( void * * ) & pce ) = = FAILURE | |
( zend_hash_quick_find ( EG ( class_table ) , Z_STRVAL_P ( opline - > op1 . zv ) , Z_STRLEN_P ( opline - > op1 . zv ) , Z_HASH_P ( opline - > op1 . zv ) , ( void * * ) & pce_orig ) = = SUCCESS & &
2008-03-18 16:36:30 +08:00
* pce ! = * pce_orig ) ) {
2010-04-20 18:57:45 +08:00
do_bind_inherited_class ( EX ( op_array ) , opline , EG ( class_table ) , EX_T ( opline - > extended_value ) . class_entry , 0 TSRMLS_CC ) ;
2008-03-18 16:36:30 +08:00
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2008-03-18 16:36:30 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
ZEND_VM_HANDLER ( 141 , ZEND_DECLARE_FUNCTION , ANY , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
SAVE_OPLINE ( ) ;
do_bind_function ( EX ( op_array ) , opline , EG ( function_table ) , 0 ) ;
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2010-04-20 18:57:45 +08:00
ZEND_VM_HANDLER ( 105 , ZEND_TICKS , ANY , ANY )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-04-20 18:57:45 +08:00
if ( + + EG ( ticks_count ) > = opline - > extended_value ) {
2004-10-23 05:42:14 +08:00
EG ( ticks_count ) = 0 ;
if ( zend_ticks_function ) {
2010-04-20 18:57:45 +08:00
zend_ticks_function ( opline - > extended_value ) ;
2004-10-23 05:42:14 +08:00
}
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 138 , ZEND_INSTANCEOF , TMP | VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
zval * expr ;
2004-10-23 05:42:14 +08:00
zend_bool result ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
expr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2011-03-16 13:25:02 +08:00
2005-06-28 18:49:56 +08:00
if ( Z_TYPE_P ( expr ) = = IS_OBJECT & & Z_OBJ_HT_P ( expr ) - > get_class_entry ) {
2010-04-20 18:57:45 +08:00
result = instanceof_function ( Z_OBJCE_P ( expr ) , EX_T ( opline - > op2 . var ) . class_entry TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
} else {
result = 0 ;
}
2010-04-20 18:57:45 +08:00
ZVAL_BOOL ( & EX_T ( opline - > result . var ) . tmp_var , result ) ;
2004-10-23 05:42:14 +08:00
FREE_OP1 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 104 , ZEND_EXT_NOP , ANY , ANY )
{
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 0 , ZEND_NOP , ANY , ANY )
{
ZEND_VM_NEXT_OPCODE ( ) ;
}
2008-03-12 18:32:12 +08:00
ZEND_VM_HANDLER ( 144 , ZEND_ADD_INTERFACE , ANY , CONST )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2010-04-20 18:57:45 +08:00
zend_class_entry * ce = EX_T ( opline - > op1 . var ) . class_entry ;
2010-04-20 19:16:39 +08:00
zend_class_entry * iface ;
SAVE_OPLINE ( ) ;
2010-05-24 22:11:39 +08:00
if ( CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ) {
iface = CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ;
} else {
iface = zend_fetch_class_by_name ( Z_STRVAL_P ( opline - > op2 . zv ) , Z_STRLEN_P ( opline - > op2 . zv ) , opline - > op2 . literal + 1 , opline - > extended_value TSRMLS_CC ) ;
if ( UNEXPECTED ( iface = = NULL ) ) {
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2009-11-02 05:26:03 +08:00
}
2010-05-24 22:11:39 +08:00
CACHE_PTR ( opline - > op2 . literal - > cache_slot , ce ) ;
}
if ( UNEXPECTED ( ( iface - > ce_flags & ZEND_ACC_INTERFACE ) = = 0 ) ) {
zend_error_noreturn ( E_ERROR , " %s cannot implement %s - it is not an interface " , ce - > name , iface - > name ) ;
2004-10-23 05:42:14 +08:00
}
2010-05-24 22:11:39 +08:00
zend_do_implement_interface ( ce , iface TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
Implemented Traits for PHP as proposed in the RFC [TRAITS]
# RFC http://wiki.php.net/rfc/horizontalreuse#traits_-_reuse_of_behavior
# Ok, here we go, I guess that will result in more discussion, which is fine
# by me. But now, the patch is here, and properly archived.
#
# See below a list of notes to the patch, it also includes a list of
# points which should be fixed
#
# Internals of the Traits Patch
# -----------------------------
#
# Open TODOs
# """"""""""
#
# - Reflection API
# - support for traits for internal classes
# - currently destroy_zend_class does not handle that case
#
# Introduced Structures
# """""""""""""""""""""
#
# Data structures to encode the composition information specified in the
# source:
# - zend_trait_method_reference
# - zend_trait_precedence
# - zend_trait_alias
#
# Changes
# """""""
#
# zend_class_entry
# - uses NULL terminated lists of pointers for
# - trait_aliases
# - trait_precedences
# - do you prefer an explicit counter?
# - the information is only necessary during class composition
# but might be interesting for reflection
# - did not want to blow up class further with not really necessary length counters
#
# added keywords
# - trait
# - insteadof
#
# Added opcodes
# ZEND_ADD_TRAIT
# - similar to ZEND_ADD_INTERFACE
# - adds the trait to the list of traits of a class, no actual composition done
# ZEND_BIND_TRAITS
# - emitted in zend_do_end_class_declaration
# - concludes the class definition and will initiate the trait composition
# when the class definition is encountered during runtime
#
# Added Flags
# ZEND_ACC_TRAIT = 0x120
# ZEND_ACC_IMPLEMENT_TRAITS = 0x400000
# ZEND_FETCH_CLASS_TRAIT = 14
#
# zend_vm_execute.h
# - not sure whether the handler initialization (ZEND_ADD_TRAIT_SPEC_HANDLER,
# ZEND_BIND_TRAITS_SPEC_HANDLER) is correct, maybe it should be more selective
#
# zend_compile.c
# - refactored do_inherit_method_check
# split into do_inherit_method_check and do_inheritance_check_on_method
# - added helper functions use a '_' as prefix and are not mentioned in the
# headers
# - _copy_functions
# prepare hash-maps of functions which should be merged into a class
# here the aliases are handled
# - _merge_functions
# builds a hash-table of the methods which need to be added to a class
# does the conflict detection
# - reused php_runkit_function_copy_ctor
# - it is not identical with the original code anymore, needed to update it
# think I fixed some bugs, not sure whether all have been reported back to runkit
# - has to be renamed, left the name for the moment, to make its origin obvious
# - here might be optimization potential
# - not sure whether everything needs to be copied
# - copying the literals might be broken
# - added it since the literals array is freed by efree and gave problems
# with doubled frees
# - all immutable parts of the zend_op array should not be copied
# - am not sure which parts are immutable
# - and not sure how to avoid doubled frees on the same arrays on shutdown
# - _merge_functions_to_class
# does the final merging with the target class to handle inherited
# and overridden methods
# - small helper for NULL terminated lists
# zend_init_list, zend_add_to_list
#
# zend_language_parser.y
# - reused class definition for traits
# - there should be something with regard to properties
# - if they get explicitly defined, it might be worthwhile to
# check that there are no collisions with other traits in a composition
# (however, I would not introduce elaborate language features to control that
# but a notice for such conflicts might be nice to the developers)
2010-04-23 06:05:56 +08:00
ZEND_VM_HANDLER ( 154 , ZEND_ADD_TRAIT , ANY , ANY )
{
2011-05-06 00:02:11 +08:00
USE_OPLINE
Implemented Traits for PHP as proposed in the RFC [TRAITS]
# RFC http://wiki.php.net/rfc/horizontalreuse#traits_-_reuse_of_behavior
# Ok, here we go, I guess that will result in more discussion, which is fine
# by me. But now, the patch is here, and properly archived.
#
# See below a list of notes to the patch, it also includes a list of
# points which should be fixed
#
# Internals of the Traits Patch
# -----------------------------
#
# Open TODOs
# """"""""""
#
# - Reflection API
# - support for traits for internal classes
# - currently destroy_zend_class does not handle that case
#
# Introduced Structures
# """""""""""""""""""""
#
# Data structures to encode the composition information specified in the
# source:
# - zend_trait_method_reference
# - zend_trait_precedence
# - zend_trait_alias
#
# Changes
# """""""
#
# zend_class_entry
# - uses NULL terminated lists of pointers for
# - trait_aliases
# - trait_precedences
# - do you prefer an explicit counter?
# - the information is only necessary during class composition
# but might be interesting for reflection
# - did not want to blow up class further with not really necessary length counters
#
# added keywords
# - trait
# - insteadof
#
# Added opcodes
# ZEND_ADD_TRAIT
# - similar to ZEND_ADD_INTERFACE
# - adds the trait to the list of traits of a class, no actual composition done
# ZEND_BIND_TRAITS
# - emitted in zend_do_end_class_declaration
# - concludes the class definition and will initiate the trait composition
# when the class definition is encountered during runtime
#
# Added Flags
# ZEND_ACC_TRAIT = 0x120
# ZEND_ACC_IMPLEMENT_TRAITS = 0x400000
# ZEND_FETCH_CLASS_TRAIT = 14
#
# zend_vm_execute.h
# - not sure whether the handler initialization (ZEND_ADD_TRAIT_SPEC_HANDLER,
# ZEND_BIND_TRAITS_SPEC_HANDLER) is correct, maybe it should be more selective
#
# zend_compile.c
# - refactored do_inherit_method_check
# split into do_inherit_method_check and do_inheritance_check_on_method
# - added helper functions use a '_' as prefix and are not mentioned in the
# headers
# - _copy_functions
# prepare hash-maps of functions which should be merged into a class
# here the aliases are handled
# - _merge_functions
# builds a hash-table of the methods which need to be added to a class
# does the conflict detection
# - reused php_runkit_function_copy_ctor
# - it is not identical with the original code anymore, needed to update it
# think I fixed some bugs, not sure whether all have been reported back to runkit
# - has to be renamed, left the name for the moment, to make its origin obvious
# - here might be optimization potential
# - not sure whether everything needs to be copied
# - copying the literals might be broken
# - added it since the literals array is freed by efree and gave problems
# with doubled frees
# - all immutable parts of the zend_op array should not be copied
# - am not sure which parts are immutable
# - and not sure how to avoid doubled frees on the same arrays on shutdown
# - _merge_functions_to_class
# does the final merging with the target class to handle inherited
# and overridden methods
# - small helper for NULL terminated lists
# zend_init_list, zend_add_to_list
#
# zend_language_parser.y
# - reused class definition for traits
# - there should be something with regard to properties
# - if they get explicitly defined, it might be worthwhile to
# check that there are no collisions with other traits in a composition
# (however, I would not introduce elaborate language features to control that
# but a notice for such conflicts might be nice to the developers)
2010-04-23 06:05:56 +08:00
zend_class_entry * ce = EX_T ( opline - > op1 . var ) . class_entry ;
2010-05-24 22:11:39 +08:00
zend_class_entry * trait ;
2011-05-06 00:02:11 +08:00
SAVE_OPLINE ( ) ;
2010-05-24 22:11:39 +08:00
if ( CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ) {
trait = CACHED_PTR ( opline - > op2 . literal - > cache_slot ) ;
} else {
trait = zend_fetch_class_by_name ( Z_STRVAL_P ( opline - > op2 . zv ) ,
Z_STRLEN_P ( opline - > op2 . zv ) ,
opline - > op2 . literal + 1 ,
opline - > extended_value TSRMLS_CC ) ;
if ( UNEXPECTED ( trait = = NULL ) ) {
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2010-05-07 19:09:35 +08:00
if ( ! ( ( trait - > ce_flags & ZEND_ACC_TRAIT ) = = ZEND_ACC_TRAIT ) ) {
Implemented Traits for PHP as proposed in the RFC [TRAITS]
# RFC http://wiki.php.net/rfc/horizontalreuse#traits_-_reuse_of_behavior
# Ok, here we go, I guess that will result in more discussion, which is fine
# by me. But now, the patch is here, and properly archived.
#
# See below a list of notes to the patch, it also includes a list of
# points which should be fixed
#
# Internals of the Traits Patch
# -----------------------------
#
# Open TODOs
# """"""""""
#
# - Reflection API
# - support for traits for internal classes
# - currently destroy_zend_class does not handle that case
#
# Introduced Structures
# """""""""""""""""""""
#
# Data structures to encode the composition information specified in the
# source:
# - zend_trait_method_reference
# - zend_trait_precedence
# - zend_trait_alias
#
# Changes
# """""""
#
# zend_class_entry
# - uses NULL terminated lists of pointers for
# - trait_aliases
# - trait_precedences
# - do you prefer an explicit counter?
# - the information is only necessary during class composition
# but might be interesting for reflection
# - did not want to blow up class further with not really necessary length counters
#
# added keywords
# - trait
# - insteadof
#
# Added opcodes
# ZEND_ADD_TRAIT
# - similar to ZEND_ADD_INTERFACE
# - adds the trait to the list of traits of a class, no actual composition done
# ZEND_BIND_TRAITS
# - emitted in zend_do_end_class_declaration
# - concludes the class definition and will initiate the trait composition
# when the class definition is encountered during runtime
#
# Added Flags
# ZEND_ACC_TRAIT = 0x120
# ZEND_ACC_IMPLEMENT_TRAITS = 0x400000
# ZEND_FETCH_CLASS_TRAIT = 14
#
# zend_vm_execute.h
# - not sure whether the handler initialization (ZEND_ADD_TRAIT_SPEC_HANDLER,
# ZEND_BIND_TRAITS_SPEC_HANDLER) is correct, maybe it should be more selective
#
# zend_compile.c
# - refactored do_inherit_method_check
# split into do_inherit_method_check and do_inheritance_check_on_method
# - added helper functions use a '_' as prefix and are not mentioned in the
# headers
# - _copy_functions
# prepare hash-maps of functions which should be merged into a class
# here the aliases are handled
# - _merge_functions
# builds a hash-table of the methods which need to be added to a class
# does the conflict detection
# - reused php_runkit_function_copy_ctor
# - it is not identical with the original code anymore, needed to update it
# think I fixed some bugs, not sure whether all have been reported back to runkit
# - has to be renamed, left the name for the moment, to make its origin obvious
# - here might be optimization potential
# - not sure whether everything needs to be copied
# - copying the literals might be broken
# - added it since the literals array is freed by efree and gave problems
# with doubled frees
# - all immutable parts of the zend_op array should not be copied
# - am not sure which parts are immutable
# - and not sure how to avoid doubled frees on the same arrays on shutdown
# - _merge_functions_to_class
# does the final merging with the target class to handle inherited
# and overridden methods
# - small helper for NULL terminated lists
# zend_init_list, zend_add_to_list
#
# zend_language_parser.y
# - reused class definition for traits
# - there should be something with regard to properties
# - if they get explicitly defined, it might be worthwhile to
# check that there are no collisions with other traits in a composition
# (however, I would not introduce elaborate language features to control that
# but a notice for such conflicts might be nice to the developers)
2010-04-23 06:05:56 +08:00
zend_error_noreturn ( E_ERROR , " %s cannot use %s - it is not a trait " , ce - > name , trait - > name ) ;
}
2010-05-24 22:11:39 +08:00
CACHE_PTR ( opline - > op2 . literal - > cache_slot , trait ) ;
Implemented Traits for PHP as proposed in the RFC [TRAITS]
# RFC http://wiki.php.net/rfc/horizontalreuse#traits_-_reuse_of_behavior
# Ok, here we go, I guess that will result in more discussion, which is fine
# by me. But now, the patch is here, and properly archived.
#
# See below a list of notes to the patch, it also includes a list of
# points which should be fixed
#
# Internals of the Traits Patch
# -----------------------------
#
# Open TODOs
# """"""""""
#
# - Reflection API
# - support for traits for internal classes
# - currently destroy_zend_class does not handle that case
#
# Introduced Structures
# """""""""""""""""""""
#
# Data structures to encode the composition information specified in the
# source:
# - zend_trait_method_reference
# - zend_trait_precedence
# - zend_trait_alias
#
# Changes
# """""""
#
# zend_class_entry
# - uses NULL terminated lists of pointers for
# - trait_aliases
# - trait_precedences
# - do you prefer an explicit counter?
# - the information is only necessary during class composition
# but might be interesting for reflection
# - did not want to blow up class further with not really necessary length counters
#
# added keywords
# - trait
# - insteadof
#
# Added opcodes
# ZEND_ADD_TRAIT
# - similar to ZEND_ADD_INTERFACE
# - adds the trait to the list of traits of a class, no actual composition done
# ZEND_BIND_TRAITS
# - emitted in zend_do_end_class_declaration
# - concludes the class definition and will initiate the trait composition
# when the class definition is encountered during runtime
#
# Added Flags
# ZEND_ACC_TRAIT = 0x120
# ZEND_ACC_IMPLEMENT_TRAITS = 0x400000
# ZEND_FETCH_CLASS_TRAIT = 14
#
# zend_vm_execute.h
# - not sure whether the handler initialization (ZEND_ADD_TRAIT_SPEC_HANDLER,
# ZEND_BIND_TRAITS_SPEC_HANDLER) is correct, maybe it should be more selective
#
# zend_compile.c
# - refactored do_inherit_method_check
# split into do_inherit_method_check and do_inheritance_check_on_method
# - added helper functions use a '_' as prefix and are not mentioned in the
# headers
# - _copy_functions
# prepare hash-maps of functions which should be merged into a class
# here the aliases are handled
# - _merge_functions
# builds a hash-table of the methods which need to be added to a class
# does the conflict detection
# - reused php_runkit_function_copy_ctor
# - it is not identical with the original code anymore, needed to update it
# think I fixed some bugs, not sure whether all have been reported back to runkit
# - has to be renamed, left the name for the moment, to make its origin obvious
# - here might be optimization potential
# - not sure whether everything needs to be copied
# - copying the literals might be broken
# - added it since the literals array is freed by efree and gave problems
# with doubled frees
# - all immutable parts of the zend_op array should not be copied
# - am not sure which parts are immutable
# - and not sure how to avoid doubled frees on the same arrays on shutdown
# - _merge_functions_to_class
# does the final merging with the target class to handle inherited
# and overridden methods
# - small helper for NULL terminated lists
# zend_init_list, zend_add_to_list
#
# zend_language_parser.y
# - reused class definition for traits
# - there should be something with regard to properties
# - if they get explicitly defined, it might be worthwhile to
# check that there are no collisions with other traits in a composition
# (however, I would not introduce elaborate language features to control that
# but a notice for such conflicts might be nice to the developers)
2010-04-23 06:05:56 +08:00
}
2010-05-24 22:11:39 +08:00
zend_do_implement_trait ( ce , trait TSRMLS_CC ) ;
2010-05-06 20:52:27 +08:00
CHECK_EXCEPTION ( ) ;
Implemented Traits for PHP as proposed in the RFC [TRAITS]
# RFC http://wiki.php.net/rfc/horizontalreuse#traits_-_reuse_of_behavior
# Ok, here we go, I guess that will result in more discussion, which is fine
# by me. But now, the patch is here, and properly archived.
#
# See below a list of notes to the patch, it also includes a list of
# points which should be fixed
#
# Internals of the Traits Patch
# -----------------------------
#
# Open TODOs
# """"""""""
#
# - Reflection API
# - support for traits for internal classes
# - currently destroy_zend_class does not handle that case
#
# Introduced Structures
# """""""""""""""""""""
#
# Data structures to encode the composition information specified in the
# source:
# - zend_trait_method_reference
# - zend_trait_precedence
# - zend_trait_alias
#
# Changes
# """""""
#
# zend_class_entry
# - uses NULL terminated lists of pointers for
# - trait_aliases
# - trait_precedences
# - do you prefer an explicit counter?
# - the information is only necessary during class composition
# but might be interesting for reflection
# - did not want to blow up class further with not really necessary length counters
#
# added keywords
# - trait
# - insteadof
#
# Added opcodes
# ZEND_ADD_TRAIT
# - similar to ZEND_ADD_INTERFACE
# - adds the trait to the list of traits of a class, no actual composition done
# ZEND_BIND_TRAITS
# - emitted in zend_do_end_class_declaration
# - concludes the class definition and will initiate the trait composition
# when the class definition is encountered during runtime
#
# Added Flags
# ZEND_ACC_TRAIT = 0x120
# ZEND_ACC_IMPLEMENT_TRAITS = 0x400000
# ZEND_FETCH_CLASS_TRAIT = 14
#
# zend_vm_execute.h
# - not sure whether the handler initialization (ZEND_ADD_TRAIT_SPEC_HANDLER,
# ZEND_BIND_TRAITS_SPEC_HANDLER) is correct, maybe it should be more selective
#
# zend_compile.c
# - refactored do_inherit_method_check
# split into do_inherit_method_check and do_inheritance_check_on_method
# - added helper functions use a '_' as prefix and are not mentioned in the
# headers
# - _copy_functions
# prepare hash-maps of functions which should be merged into a class
# here the aliases are handled
# - _merge_functions
# builds a hash-table of the methods which need to be added to a class
# does the conflict detection
# - reused php_runkit_function_copy_ctor
# - it is not identical with the original code anymore, needed to update it
# think I fixed some bugs, not sure whether all have been reported back to runkit
# - has to be renamed, left the name for the moment, to make its origin obvious
# - here might be optimization potential
# - not sure whether everything needs to be copied
# - copying the literals might be broken
# - added it since the literals array is freed by efree and gave problems
# with doubled frees
# - all immutable parts of the zend_op array should not be copied
# - am not sure which parts are immutable
# - and not sure how to avoid doubled frees on the same arrays on shutdown
# - _merge_functions_to_class
# does the final merging with the target class to handle inherited
# and overridden methods
# - small helper for NULL terminated lists
# zend_init_list, zend_add_to_list
#
# zend_language_parser.y
# - reused class definition for traits
# - there should be something with regard to properties
# - if they get explicitly defined, it might be worthwhile to
# check that there are no collisions with other traits in a composition
# (however, I would not introduce elaborate language features to control that
# but a notice for such conflicts might be nice to the developers)
2010-04-23 06:05:56 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 155 , ZEND_BIND_TRAITS , ANY , ANY )
{
2011-05-06 00:02:11 +08:00
USE_OPLINE
Implemented Traits for PHP as proposed in the RFC [TRAITS]
# RFC http://wiki.php.net/rfc/horizontalreuse#traits_-_reuse_of_behavior
# Ok, here we go, I guess that will result in more discussion, which is fine
# by me. But now, the patch is here, and properly archived.
#
# See below a list of notes to the patch, it also includes a list of
# points which should be fixed
#
# Internals of the Traits Patch
# -----------------------------
#
# Open TODOs
# """"""""""
#
# - Reflection API
# - support for traits for internal classes
# - currently destroy_zend_class does not handle that case
#
# Introduced Structures
# """""""""""""""""""""
#
# Data structures to encode the composition information specified in the
# source:
# - zend_trait_method_reference
# - zend_trait_precedence
# - zend_trait_alias
#
# Changes
# """""""
#
# zend_class_entry
# - uses NULL terminated lists of pointers for
# - trait_aliases
# - trait_precedences
# - do you prefer an explicit counter?
# - the information is only necessary during class composition
# but might be interesting for reflection
# - did not want to blow up class further with not really necessary length counters
#
# added keywords
# - trait
# - insteadof
#
# Added opcodes
# ZEND_ADD_TRAIT
# - similar to ZEND_ADD_INTERFACE
# - adds the trait to the list of traits of a class, no actual composition done
# ZEND_BIND_TRAITS
# - emitted in zend_do_end_class_declaration
# - concludes the class definition and will initiate the trait composition
# when the class definition is encountered during runtime
#
# Added Flags
# ZEND_ACC_TRAIT = 0x120
# ZEND_ACC_IMPLEMENT_TRAITS = 0x400000
# ZEND_FETCH_CLASS_TRAIT = 14
#
# zend_vm_execute.h
# - not sure whether the handler initialization (ZEND_ADD_TRAIT_SPEC_HANDLER,
# ZEND_BIND_TRAITS_SPEC_HANDLER) is correct, maybe it should be more selective
#
# zend_compile.c
# - refactored do_inherit_method_check
# split into do_inherit_method_check and do_inheritance_check_on_method
# - added helper functions use a '_' as prefix and are not mentioned in the
# headers
# - _copy_functions
# prepare hash-maps of functions which should be merged into a class
# here the aliases are handled
# - _merge_functions
# builds a hash-table of the methods which need to be added to a class
# does the conflict detection
# - reused php_runkit_function_copy_ctor
# - it is not identical with the original code anymore, needed to update it
# think I fixed some bugs, not sure whether all have been reported back to runkit
# - has to be renamed, left the name for the moment, to make its origin obvious
# - here might be optimization potential
# - not sure whether everything needs to be copied
# - copying the literals might be broken
# - added it since the literals array is freed by efree and gave problems
# with doubled frees
# - all immutable parts of the zend_op array should not be copied
# - am not sure which parts are immutable
# - and not sure how to avoid doubled frees on the same arrays on shutdown
# - _merge_functions_to_class
# does the final merging with the target class to handle inherited
# and overridden methods
# - small helper for NULL terminated lists
# zend_init_list, zend_add_to_list
#
# zend_language_parser.y
# - reused class definition for traits
# - there should be something with regard to properties
# - if they get explicitly defined, it might be worthwhile to
# check that there are no collisions with other traits in a composition
# (however, I would not introduce elaborate language features to control that
# but a notice for such conflicts might be nice to the developers)
2010-04-23 06:05:56 +08:00
zend_class_entry * ce = EX_T ( opline - > op1 . var ) . class_entry ;
2011-03-16 13:25:02 +08:00
2011-05-06 00:02:11 +08:00
SAVE_OPLINE ( ) ;
Implemented Traits for PHP as proposed in the RFC [TRAITS]
# RFC http://wiki.php.net/rfc/horizontalreuse#traits_-_reuse_of_behavior
# Ok, here we go, I guess that will result in more discussion, which is fine
# by me. But now, the patch is here, and properly archived.
#
# See below a list of notes to the patch, it also includes a list of
# points which should be fixed
#
# Internals of the Traits Patch
# -----------------------------
#
# Open TODOs
# """"""""""
#
# - Reflection API
# - support for traits for internal classes
# - currently destroy_zend_class does not handle that case
#
# Introduced Structures
# """""""""""""""""""""
#
# Data structures to encode the composition information specified in the
# source:
# - zend_trait_method_reference
# - zend_trait_precedence
# - zend_trait_alias
#
# Changes
# """""""
#
# zend_class_entry
# - uses NULL terminated lists of pointers for
# - trait_aliases
# - trait_precedences
# - do you prefer an explicit counter?
# - the information is only necessary during class composition
# but might be interesting for reflection
# - did not want to blow up class further with not really necessary length counters
#
# added keywords
# - trait
# - insteadof
#
# Added opcodes
# ZEND_ADD_TRAIT
# - similar to ZEND_ADD_INTERFACE
# - adds the trait to the list of traits of a class, no actual composition done
# ZEND_BIND_TRAITS
# - emitted in zend_do_end_class_declaration
# - concludes the class definition and will initiate the trait composition
# when the class definition is encountered during runtime
#
# Added Flags
# ZEND_ACC_TRAIT = 0x120
# ZEND_ACC_IMPLEMENT_TRAITS = 0x400000
# ZEND_FETCH_CLASS_TRAIT = 14
#
# zend_vm_execute.h
# - not sure whether the handler initialization (ZEND_ADD_TRAIT_SPEC_HANDLER,
# ZEND_BIND_TRAITS_SPEC_HANDLER) is correct, maybe it should be more selective
#
# zend_compile.c
# - refactored do_inherit_method_check
# split into do_inherit_method_check and do_inheritance_check_on_method
# - added helper functions use a '_' as prefix and are not mentioned in the
# headers
# - _copy_functions
# prepare hash-maps of functions which should be merged into a class
# here the aliases are handled
# - _merge_functions
# builds a hash-table of the methods which need to be added to a class
# does the conflict detection
# - reused php_runkit_function_copy_ctor
# - it is not identical with the original code anymore, needed to update it
# think I fixed some bugs, not sure whether all have been reported back to runkit
# - has to be renamed, left the name for the moment, to make its origin obvious
# - here might be optimization potential
# - not sure whether everything needs to be copied
# - copying the literals might be broken
# - added it since the literals array is freed by efree and gave problems
# with doubled frees
# - all immutable parts of the zend_op array should not be copied
# - am not sure which parts are immutable
# - and not sure how to avoid doubled frees on the same arrays on shutdown
# - _merge_functions_to_class
# does the final merging with the target class to handle inherited
# and overridden methods
# - small helper for NULL terminated lists
# zend_init_list, zend_add_to_list
#
# zend_language_parser.y
# - reused class definition for traits
# - there should be something with regard to properties
# - if they get explicitly defined, it might be worthwhile to
# check that there are no collisions with other traits in a composition
# (however, I would not introduce elaborate language features to control that
# but a notice for such conflicts might be nice to the developers)
2010-04-23 06:05:56 +08:00
zend_do_bind_traits ( ce TSRMLS_CC ) ;
2011-05-06 00:02:11 +08:00
CHECK_EXCEPTION ( ) ;
Implemented Traits for PHP as proposed in the RFC [TRAITS]
# RFC http://wiki.php.net/rfc/horizontalreuse#traits_-_reuse_of_behavior
# Ok, here we go, I guess that will result in more discussion, which is fine
# by me. But now, the patch is here, and properly archived.
#
# See below a list of notes to the patch, it also includes a list of
# points which should be fixed
#
# Internals of the Traits Patch
# -----------------------------
#
# Open TODOs
# """"""""""
#
# - Reflection API
# - support for traits for internal classes
# - currently destroy_zend_class does not handle that case
#
# Introduced Structures
# """""""""""""""""""""
#
# Data structures to encode the composition information specified in the
# source:
# - zend_trait_method_reference
# - zend_trait_precedence
# - zend_trait_alias
#
# Changes
# """""""
#
# zend_class_entry
# - uses NULL terminated lists of pointers for
# - trait_aliases
# - trait_precedences
# - do you prefer an explicit counter?
# - the information is only necessary during class composition
# but might be interesting for reflection
# - did not want to blow up class further with not really necessary length counters
#
# added keywords
# - trait
# - insteadof
#
# Added opcodes
# ZEND_ADD_TRAIT
# - similar to ZEND_ADD_INTERFACE
# - adds the trait to the list of traits of a class, no actual composition done
# ZEND_BIND_TRAITS
# - emitted in zend_do_end_class_declaration
# - concludes the class definition and will initiate the trait composition
# when the class definition is encountered during runtime
#
# Added Flags
# ZEND_ACC_TRAIT = 0x120
# ZEND_ACC_IMPLEMENT_TRAITS = 0x400000
# ZEND_FETCH_CLASS_TRAIT = 14
#
# zend_vm_execute.h
# - not sure whether the handler initialization (ZEND_ADD_TRAIT_SPEC_HANDLER,
# ZEND_BIND_TRAITS_SPEC_HANDLER) is correct, maybe it should be more selective
#
# zend_compile.c
# - refactored do_inherit_method_check
# split into do_inherit_method_check and do_inheritance_check_on_method
# - added helper functions use a '_' as prefix and are not mentioned in the
# headers
# - _copy_functions
# prepare hash-maps of functions which should be merged into a class
# here the aliases are handled
# - _merge_functions
# builds a hash-table of the methods which need to be added to a class
# does the conflict detection
# - reused php_runkit_function_copy_ctor
# - it is not identical with the original code anymore, needed to update it
# think I fixed some bugs, not sure whether all have been reported back to runkit
# - has to be renamed, left the name for the moment, to make its origin obvious
# - here might be optimization potential
# - not sure whether everything needs to be copied
# - copying the literals might be broken
# - added it since the literals array is freed by efree and gave problems
# with doubled frees
# - all immutable parts of the zend_op array should not be copied
# - am not sure which parts are immutable
# - and not sure how to avoid doubled frees on the same arrays on shutdown
# - _merge_functions_to_class
# does the final merging with the target class to handle inherited
# and overridden methods
# - small helper for NULL terminated lists
# zend_init_list, zend_add_to_list
#
# zend_language_parser.y
# - reused class definition for traits
# - there should be something with regard to properties
# - if they get explicitly defined, it might be worthwhile to
# check that there are no collisions with other traits in a composition
# (however, I would not introduce elaborate language features to control that
# but a notice for such conflicts might be nice to the developers)
2010-04-23 06:05:56 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
ZEND_VM_HANDLER ( 149 , ZEND_HANDLE_EXCEPTION , ANY , ANY )
{
zend_uint op_num = EG ( opline_before_exception ) - EG ( active_op_array ) - > opcodes ;
int i ;
2012-08-13 21:48:39 +08:00
zend_uint catch_op_num = 0 , finally_op_num = 0 ;
2012-05-30 22:28:33 +08:00
void * * stack_frame ;
2011-03-16 13:25:02 +08:00
2012-05-30 22:28:33 +08:00
/* Figure out where the next stack frame (which maybe contains pushed
* arguments that have to be dtor ' ed ) starts */
2012-12-04 14:14:39 +08:00
stack_frame = zend_vm_stack_frame_base ( execute_data ) ;
2008-01-24 17:41:39 +08:00
2012-05-30 22:28:33 +08:00
/* If the exception was thrown during a function call there might be
* arguments pushed to the stack that have to be dtor ' ed . */
2008-01-24 17:41:39 +08:00
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 ) ;
2004-10-23 05:42:14 +08:00
}
for ( i = 0 ; i < EG ( active_op_array ) - > last_try_catch ; i + + ) {
if ( EG ( active_op_array ) - > try_catch_array [ i ] . try_op > op_num ) {
/* further blocks will not be relevant... */
break ;
2012-10-05 14:14:20 +08:00
}
2012-08-14 08:59:40 +08:00
if ( op_num < EG ( active_op_array ) - > try_catch_array [ i ] . catch_op ) {
2006-09-20 05:36:54 +08:00
catch_op_num = EX ( op_array ) - > try_catch_array [ i ] . catch_op ;
2004-10-23 05:42:14 +08:00
}
2012-08-14 08:59:40 +08:00
if ( op_num < EG ( active_op_array ) - > try_catch_array [ i ] . finally_op ) {
finally_op_num = EX ( op_array ) - > try_catch_array [ i ] . finally_op ;
}
2004-10-23 05:42:14 +08:00
}
2012-11-30 17:39:23 +08:00
if ( EX ( call ) > = EX ( call_slots ) ) {
call_slot * call = EX ( call ) ;
do {
if ( call - > object ) {
if ( call - > is_ctor_call ) {
if ( call - > is_ctor_result_used ) {
Z_DELREF_P ( call - > object ) ;
}
if ( Z_REFCOUNT_P ( call - > object ) = = 1 ) {
zend_object_store_ctor_failed ( call - > object TSRMLS_CC ) ;
}
2009-03-26 18:17:30 +08:00
}
2012-11-30 17:39:23 +08:00
zval_ptr_dtor ( & call - > object ) ;
2005-10-20 15:23:26 +08:00
}
2012-11-30 17:39:23 +08:00
call - - ;
} while ( call > = EX ( call_slots ) ) ;
EX ( call ) = NULL ;
2005-05-04 19:17:30 +08:00
}
2006-09-20 05:36:54 +08:00
for ( i = 0 ; i < EX ( op_array ) - > last_brk_cont ; i + + ) {
2008-02-20 20:05:57 +08:00
if ( EX ( op_array ) - > brk_cont_array [ i ] . start < 0 ) {
continue ;
} else if ( EX ( op_array ) - > brk_cont_array [ i ] . start > op_num ) {
2006-09-20 05:36:54 +08:00
/* further blocks will not be relevant... */
break ;
2008-02-20 20:05:57 +08:00
} else if ( op_num < EX ( op_array ) - > brk_cont_array [ i ] . brk ) {
2012-11-22 19:17:05 +08:00
if ( ! catch_op_num | |
2006-09-20 05:36:54 +08:00
catch_op_num > = EX ( op_array ) - > brk_cont_array [ i ] . brk ) {
zend_op * brk_opline = & EX ( op_array ) - > opcodes [ EX ( op_array ) - > brk_cont_array [ i ] . brk ] ;
switch ( brk_opline - > opcode ) {
case ZEND_SWITCH_FREE :
2010-04-20 18:57:45 +08:00
if ( ! ( brk_opline - > extended_value & EXT_TYPE_FREE_ON_RETURN ) ) {
2010-10-22 21:59:23 +08:00
zval_ptr_dtor ( & EX_T ( brk_opline - > op1 . var ) . var . ptr ) ;
2008-05-05 19:03:35 +08:00
}
2006-09-20 05:36:54 +08:00
break ;
case ZEND_FREE :
2010-04-20 18:57:45 +08:00
if ( ! ( brk_opline - > extended_value & EXT_TYPE_FREE_ON_RETURN ) ) {
zendi_zval_dtor ( EX_T ( brk_opline - > op1 . var ) . tmp_var ) ;
2008-05-05 19:03:35 +08:00
}
2006-09-20 05:36:54 +08:00
break ;
}
}
}
}
2005-09-23 03:03:18 +08:00
/* restore previous error_reporting value */
2006-05-12 05:07:39 +08:00
if ( ! EG ( error_reporting ) & & EX ( old_error_reporting ) ! = NULL & & Z_LVAL_P ( EX ( old_error_reporting ) ) ! = 0 ) {
2012-05-30 22:28:33 +08:00
zval restored_error_reporting ;
2006-05-12 05:07:39 +08:00
Z_TYPE ( restored_error_reporting ) = IS_LONG ;
Z_LVAL ( restored_error_reporting ) = Z_LVAL_P ( EX ( old_error_reporting ) ) ;
2005-09-23 03:03:18 +08:00
convert_to_string ( & restored_error_reporting ) ;
2007-09-28 00:55:25 +08:00
zend_alter_ini_entry_ex ( " error_reporting " , sizeof ( " error_reporting " ) , Z_STRVAL ( restored_error_reporting ) , Z_STRLEN ( restored_error_reporting ) , ZEND_INI_USER , ZEND_INI_STAGE_RUNTIME , 1 TSRMLS_CC ) ;
2005-09-23 03:03:18 +08:00
zendi_zval_dtor ( restored_error_reporting ) ;
}
EX ( old_error_reporting ) = NULL ;
2006-05-12 05:07:39 +08:00
2012-11-22 19:17:05 +08:00
if ( finally_op_num & & ( ! catch_op_num | | catch_op_num > = finally_op_num ) ) {
2012-08-14 08:59:40 +08:00
zend_exception_save ( TSRMLS_C ) ;
2012-11-22 19:17:05 +08:00
EX ( fast_ret ) = NULL ;
2012-08-14 08:59:40 +08:00
ZEND_VM_SET_OPCODE ( & EX ( op_array ) - > opcodes [ finally_op_num ] ) ;
ZEND_VM_CONTINUE ( ) ;
2012-11-22 19:17:05 +08:00
} else if ( catch_op_num ) {
ZEND_VM_SET_OPCODE ( & EX ( op_array ) - > opcodes [ catch_op_num ] ) ;
ZEND_VM_CONTINUE ( ) ;
2012-08-14 08:59:40 +08:00
} else {
2012-12-11 21:25:32 +08:00
if ( UNEXPECTED ( ( EX ( op_array ) - > fn_flags & ZEND_ACC_GENERATOR ) ! = 0 ) ) {
ZEND_VM_DISPATCH_TO_HANDLER ( ZEND_GENERATOR_RETURN ) ;
} else {
ZEND_VM_DISPATCH_TO_HELPER ( zend_leave_helper ) ;
}
2012-08-14 08:59:40 +08:00
}
2004-10-23 05:42:14 +08:00
}
ZEND_VM_HANDLER ( 146 , ZEND_VERIFY_ABSTRACT_CLASS , ANY , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
SAVE_OPLINE ( ) ;
zend_verify_abstract_class ( EX_T ( opline - > op1 . var ) . class_entry TSRMLS_CC ) ;
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2005-06-10 17:54:38 +08:00
ZEND_VM_HANDLER ( 150 , ZEND_USER_OPCODE , ANY , ANY )
2006-05-12 05:07:39 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
int ret ;
2011-03-16 13:25:02 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
ret = zend_user_opcode_handlers [ opline - > opcode ] ( ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL ) ;
LOAD_OPLINE ( ) ;
2005-06-16 14:00:48 +08:00
switch ( ret ) {
2005-06-10 17:54:38 +08:00
case ZEND_USER_OPCODE_CONTINUE :
ZEND_VM_CONTINUE ( ) ;
case ZEND_USER_OPCODE_RETURN :
2012-12-11 21:25:32 +08:00
if ( UNEXPECTED ( ( EX ( op_array ) - > fn_flags & ZEND_ACC_GENERATOR ) ! = 0 ) ) {
ZEND_VM_DISPATCH_TO_HANDLER ( ZEND_GENERATOR_RETURN ) ;
} else {
ZEND_VM_DISPATCH_TO_HELPER ( zend_leave_helper ) ;
}
2009-08-18 18:12:32 +08:00
case ZEND_USER_OPCODE_ENTER :
ZEND_VM_ENTER ( ) ;
case ZEND_USER_OPCODE_LEAVE :
ZEND_VM_LEAVE ( ) ;
2005-06-10 17:54:38 +08:00
case ZEND_USER_OPCODE_DISPATCH :
2010-04-20 19:16:39 +08:00
ZEND_VM_DISPATCH ( opline - > opcode , opline ) ;
2005-06-10 17:54:38 +08:00
default :
2010-04-20 19:16:39 +08:00
ZEND_VM_DISPATCH ( ( zend_uchar ) ( ret & 0xff ) , opline ) ;
2005-06-10 17:54:38 +08:00
}
}
2007-09-29 03:52:53 +08:00
ZEND_VM_HANDLER ( 143 , ZEND_DECLARE_CONST , CONST , CONST )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2007-09-29 03:52:53 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
zval * name ;
zval * val ;
2007-09-29 03:52:53 +08:00
zend_constant c ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
name = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
val = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2007-09-29 03:52:53 +08:00
if ( ( Z_TYPE_P ( val ) & IS_CONSTANT_TYPE_MASK ) = = IS_CONSTANT | | Z_TYPE_P ( val ) = = IS_CONSTANT_ARRAY ) {
2010-04-20 19:16:39 +08:00
zval tmp ;
2007-09-29 03:52:53 +08:00
zval * tmp_ptr = & tmp ;
2010-04-20 19:16:39 +08:00
ZVAL_COPY_VALUE ( & tmp , val ) ;
2007-09-29 03:52:53 +08:00
if ( Z_TYPE_P ( val ) = = IS_CONSTANT_ARRAY ) {
2007-10-03 14:49:15 +08:00
zval_copy_ctor ( & tmp ) ;
2007-09-29 03:52:53 +08:00
}
INIT_PZVAL ( & tmp ) ;
zval_update_constant ( & tmp_ptr , NULL TSRMLS_CC ) ;
c . value = * tmp_ptr ;
} else {
2010-04-20 19:16:39 +08:00
INIT_PZVAL_COPY ( & c . value , val ) ;
2007-09-29 03:52:53 +08:00
zval_copy_ctor ( & c . value ) ;
}
c . flags = CONST_CS ; /* non persistent, case sensetive */
2010-04-20 19:05:54 +08:00
c . name = IS_INTERNED ( Z_STRVAL_P ( name ) ) ? Z_STRVAL_P ( name ) : zend_strndup ( Z_STRVAL_P ( name ) , Z_STRLEN_P ( name ) ) ;
2007-09-29 03:52:53 +08:00
c . name_len = Z_STRLEN_P ( name ) + 1 ;
c . module_number = PHP_USER_CONSTANT ;
if ( zend_register_constant ( & c TSRMLS_CC ) = = FAILURE ) {
}
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2007-09-29 03:52:53 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2010-04-20 18:57:45 +08:00
ZEND_VM_HANDLER ( 153 , ZEND_DECLARE_LAMBDA_FUNCTION , CONST , UNUSED )
2008-07-14 17:49:03 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2008-07-14 20:18:23 +08:00
zend_function * op_array ;
2008-07-14 17:49:03 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
if ( UNEXPECTED ( zend_hash_quick_find ( EG ( function_table ) , Z_STRVAL_P ( opline - > op1 . zv ) , Z_STRLEN_P ( opline - > op1 . zv ) , Z_HASH_P ( opline - > op1 . zv ) , ( void * ) & op_array ) = = FAILURE ) | |
UNEXPECTED ( op_array - > type ! = ZEND_USER_FUNCTION ) ) {
2008-07-14 17:49:03 +08:00
zend_error_noreturn ( E_ERROR , " Base lambda function for closure not found " ) ;
}
2012-09-17 04:01:07 +08:00
zend_create_closure ( & EX_T ( opline - > result . var ) . tmp_var , ( zend_function * ) op_array , EG ( scope ) , EG ( This ) TSRMLS_CC ) ;
2008-07-14 17:49:03 +08:00
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2008-07-14 17:49:03 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2010-08-25 17:14:36 +08:00
ZEND_VM_HANDLER ( 156 , ZEND_SEPARATE , VAR , UNUSED )
{
USE_OPLINE
zval * var_ptr , * new_zv ;
SAVE_OPLINE ( ) ;
var_ptr = EX_T ( opline - > op1 . var ) . var . ptr ;
if ( Z_TYPE_P ( var_ptr ) ! = IS_OBJECT & &
2012-08-14 08:59:40 +08:00
! PZVAL_IS_REF ( var_ptr ) & &
Z_REFCOUNT_P ( var_ptr ) > 1 ) {
2010-08-25 17:14:36 +08:00
Z_DELREF_P ( var_ptr ) ;
ALLOC_ZVAL ( new_zv ) ;
INIT_PZVAL_COPY ( new_zv , var_ptr ) ;
var_ptr = new_zv ;
zval_copy_ctor ( var_ptr ) ;
EX_T ( opline - > op1 . var ) . var . ptr = var_ptr ;
}
ZEND_VM_NEXT_OPCODE ( ) ;
}
2012-08-13 22:51:41 +08:00
ZEND_VM_HANDLER ( 160 , ZEND_YIELD , CONST | TMP | VAR | CV | UNUSED , CONST | TMP | VAR | CV | UNUSED )
2012-05-27 04:44:53 +08:00
{
2012-05-29 23:34:33 +08:00
USE_OPLINE
2012-05-27 04:44:53 +08:00
/* The generator object is stored in return_value_ptr_ptr */
2012-06-23 20:43:52 +08:00
zend_generator * generator = ( zend_generator * ) EG ( return_value_ptr_ptr ) ;
2012-05-27 04:44:53 +08:00
2012-08-25 23:40:08 +08:00
if ( generator - > flags & ZEND_GENERATOR_FORCED_CLOSE ) {
zend_error_noreturn ( E_ERROR , " Cannot yield from finally in a force-closed generator " ) ;
}
2012-05-27 04:44:53 +08:00
/* Destroy the previously yielded value */
if ( generator - > value ) {
zval_ptr_dtor ( & generator - > value ) ;
}
2012-05-30 08:44:06 +08:00
/* Destroy the previously yielded key */
if ( generator - > key ) {
zval_ptr_dtor ( & generator - > key ) ;
}
2012-05-29 23:34:33 +08:00
/* Set the new yielded value */
2012-05-29 23:53:11 +08:00
if ( OP1_TYPE ! = IS_UNUSED ) {
2012-07-20 23:38:39 +08:00
zend_free_op free_op1 ;
2012-07-17 19:24:27 +08:00
if ( EX ( op_array ) - > fn_flags & ZEND_ACC_RETURN_REFERENCE ) {
/* Constants and temporary variables aren't yieldable by reference,
* but we still allow them with a notice . */
if ( OP1_TYPE = = IS_CONST | | OP1_TYPE = = IS_TMP_VAR ) {
zval * value , * copy ;
2012-05-27 04:44:53 +08:00
2012-07-17 19:24:27 +08:00
zend_error ( E_NOTICE , " Only variable references should be yielded by reference " ) ;
2012-05-27 04:44:53 +08:00
2012-07-17 19:24:27 +08:00
value = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
ALLOC_ZVAL ( copy ) ;
INIT_PZVAL_COPY ( copy , value ) ;
2012-05-27 04:44:53 +08:00
2012-07-17 19:24:27 +08:00
/* Temporary variables don't need ctor copying */
if ( ! IS_OP1_TMP_FREE ( ) ) {
zval_copy_ctor ( copy ) ;
}
generator - > value = copy ;
} else {
zval * * value_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2012-05-27 04:44:53 +08:00
2012-07-17 19:24:27 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( value_ptr = = NULL ) ) {
zend_error_noreturn ( E_ERROR , " Cannot yield string offsets by reference " ) ;
}
/* If a function call result is yielded and the function did
* not return by reference we throw a notice . */
if ( OP1_TYPE = = IS_VAR & & ! Z_ISREF_PP ( value_ptr )
& & ! ( opline - > extended_value = = ZEND_RETURNS_FUNCTION
& & EX_T ( opline - > op1 . var ) . var . fcall_returned_reference )
& & EX_T ( opline - > op1 . var ) . var . ptr_ptr = = & EX_T ( opline - > op1 . var ) . var . ptr ) {
zend_error ( E_NOTICE , " Only variable references should be yielded by reference " ) ;
Z_ADDREF_PP ( value_ptr ) ;
generator - > value = * value_ptr ;
} else {
SEPARATE_ZVAL_TO_MAKE_IS_REF ( value_ptr ) ;
Z_ADDREF_PP ( value_ptr ) ;
generator - > value = * value_ptr ;
}
FREE_OP1_IF_VAR ( ) ;
}
2012-05-27 04:44:53 +08:00
} else {
2012-07-17 19:24:27 +08:00
zval * value = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2012-05-27 04:44:53 +08:00
2012-07-17 19:24:27 +08:00
/* 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 {
Z_ADDREF_P ( value ) ;
generator - > value = value ;
}
FREE_OP1_IF_VAR ( ) ;
}
2012-05-29 23:53:11 +08:00
} else {
2012-05-30 08:44:06 +08:00
/* If no value was specified yield null */
2012-05-29 23:53:11 +08:00
Z_ADDREF ( EG ( uninitialized_zval ) ) ;
generator - > value = & EG ( uninitialized_zval ) ;
2012-05-27 04:44:53 +08:00
}
2012-05-30 08:44:06 +08:00
/* Set the new yielded key */
if ( OP2_TYPE ! = IS_UNUSED ) {
zend_free_op free_op2 ;
zval * key = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
/* Consts, temporary variables and references need copying */
if ( OP2_TYPE = = IS_CONST | | OP2_TYPE = = IS_TMP_VAR
| | ( PZVAL_IS_REF ( key ) & & Z_REFCOUNT_P ( key ) > 0 )
) {
zval * copy ;
ALLOC_ZVAL ( copy ) ;
INIT_PZVAL_COPY ( copy , key ) ;
/* Temporary variables don't need ctor copying */
2012-09-02 02:31:40 +08:00
if ( ! IS_OP2_TMP_FREE ( ) ) {
2012-05-30 08:44:06 +08:00
zval_copy_ctor ( copy ) ;
}
generator - > key = copy ;
} else {
Z_ADDREF_P ( key ) ;
generator - > key = key ;
}
2012-05-30 11:05:49 +08:00
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 ) ;
}
2012-05-30 08:44:06 +08:00
FREE_OP2_IF_VAR ( ) ;
} else {
2012-05-30 11:05:49 +08:00
/* 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 ) ;
2012-05-30 08:44:06 +08:00
}
2012-05-29 23:34:33 +08:00
/* If a value is sent it should go into the result var */
generator - > send_target = & EX_T ( opline - > result . var ) ;
/* Initialize the sent value to NULL */
2012-12-19 04:36:48 +08:00
EX_T ( opline - > result . var ) . tmp_var = EG ( uninitialized_zval ) ;
2012-05-29 23:34:33 +08:00
2012-07-20 06:49:50 +08:00
/* We increment to the next op, so we are at the correct position when the
* generator is resumed . */
ZEND_VM_INC_OPCODE ( ) ;
2012-05-29 08:31:56 +08:00
/* 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 ( ) ;
2012-05-27 04:44:53 +08:00
ZEND_VM_RETURN ( ) ;
}
2012-12-13 06:48:51 +08:00
ZEND_VM_HANDLER ( 159 , ZEND_DISCARD_EXCEPTION , ANY , ANY )
{
if ( EG ( prev_exception ) ! = NULL ) {
/* discard the previously thrown exception */
zval_ptr_dtor ( & EG ( prev_exception ) ) ;
EG ( prev_exception ) = NULL ;
}
ZEND_VM_NEXT_OPCODE ( ) ;
}
2012-11-22 19:17:05 +08:00
ZEND_VM_HANDLER ( 162 , ZEND_FAST_CALL , ANY , ANY )
{
USE_OPLINE
if ( opline - > extended_value & &
UNEXPECTED ( EG ( prev_exception ) ! = NULL ) ) {
/* in case of unhandled exception jump to catch block instead of finally */
ZEND_VM_SET_OPCODE ( & EX ( op_array ) - > opcodes [ opline - > op2 . opline_num ] ) ;
ZEND_VM_CONTINUE ( ) ;
}
EX ( fast_ret ) = opline + 1 ;
ZEND_VM_SET_OPCODE ( opline - > op1 . jmp_addr ) ;
ZEND_VM_CONTINUE ( ) ;
}
ZEND_VM_HANDLER ( 163 , ZEND_FAST_RET , ANY , ANY )
{
if ( EX ( fast_ret ) ) {
ZEND_VM_SET_OPCODE ( EX ( fast_ret ) ) ;
ZEND_VM_CONTINUE ( ) ;
} else {
/* special case for unhandled exceptions */
USE_OPLINE
if ( opline - > extended_value = = ZEND_FAST_RET_TO_FINALLY ) {
ZEND_VM_SET_OPCODE ( & EX ( op_array ) - > opcodes [ opline - > op2 . opline_num ] ) ;
ZEND_VM_CONTINUE ( ) ;
} else if ( opline - > extended_value = = ZEND_FAST_RET_TO_CATCH ) {
zend_exception_restore ( TSRMLS_C ) ;
ZEND_VM_SET_OPCODE ( & EX ( op_array ) - > opcodes [ opline - > op2 . opline_num ] ) ;
ZEND_VM_CONTINUE ( ) ;
2012-12-11 21:25:32 +08:00
} else if ( UNEXPECTED ( ( EX ( op_array ) - > fn_flags & ZEND_ACC_GENERATOR ) ! = 0 ) ) {
zend_exception_restore ( TSRMLS_C ) ;
ZEND_VM_DISPATCH_TO_HANDLER ( ZEND_GENERATOR_RETURN ) ;
2012-11-22 19:17:05 +08:00
} else {
zend_exception_restore ( TSRMLS_C ) ;
ZEND_VM_DISPATCH_TO_HELPER ( zend_leave_helper ) ;
}
}
}
2005-06-24 20:33:53 +08:00
ZEND_VM_EXPORT_HELPER ( zend_do_fcall , zend_do_fcall_common_helper )