2005-01-10 22:57:36 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Zend Engine |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2014-01-03 11:08:10 +08:00
| Copyright ( c ) 1998 - 2014 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 ( ) ;
2014-02-10 14:04:30 +08:00
fast_add_function ( EX_VAR ( opline - > result . var ) ,
2014-02-19 05:12:05 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
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 ( 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 ( ) ;
2014-02-10 14:04:30 +08:00
fast_sub_function ( EX_VAR ( opline - > result . var ) ,
2014-02-19 05:12:05 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
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 ( 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 ( ) ;
2014-02-10 14:04:30 +08:00
fast_mul_function ( EX_VAR ( opline - > result . var ) ,
2014-02-19 05:12:05 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
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 ( 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 ( ) ;
2014-02-10 14:04:30 +08:00
fast_div_function ( EX_VAR ( opline - > result . var ) ,
2014-02-19 05:12:05 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
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 ( 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 ( ) ;
2014-02-10 14:04:30 +08:00
fast_mod_function ( EX_VAR ( opline - > result . var ) ,
2014-02-18 20:27:38 +08:00
GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR_DEREF ( 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 ( 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 ( ) ;
2014-02-10 14:04:30 +08:00
shift_left_function ( EX_VAR ( opline - > result . var ) ,
2014-02-18 20:27:38 +08:00
GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR_DEREF ( 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 ( 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 ( ) ;
2014-02-10 14:04:30 +08:00
shift_right_function ( EX_VAR ( opline - > result . var ) ,
2014-02-18 20:27:38 +08:00
GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR_DEREF ( 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 ( 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 ( ) ;
2014-02-10 14:04:30 +08:00
concat_function ( EX_VAR ( opline - > result . var ) ,
2014-02-18 20:27:38 +08:00
GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR_DEREF ( 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 ( 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 ( ) ;
2014-04-30 22:32:42 +08:00
fast_is_identical_function ( EX_VAR ( opline - > result . var ) ,
2014-02-18 20:27:38 +08:00
GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR_DEREF ( 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 ( 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 ;
2014-02-10 14:04:30 +08:00
zval * result = EX_VAR ( opline - > result . var ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-04-30 22:32:42 +08:00
fast_is_not_identical_function ( result ,
2014-02-18 20:27:38 +08:00
GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR_DEREF ( 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 ( 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 ;
2014-02-10 14:04:30 +08:00
zval * result = EX_VAR ( opline - > result . var ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-04-30 22:32:42 +08:00
fast_equal_function ( result ,
2014-04-22 03:30:19 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
2014-04-30 22:32:42 +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 ;
2014-02-10 14:04:30 +08:00
zval * result = EX_VAR ( opline - > result . var ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-04-30 22:32:42 +08:00
fast_not_equal_function ( result ,
2014-04-22 03:30:19 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
2014-04-30 22:32:42 +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 ;
2014-02-10 14:04:30 +08:00
zval * result = EX_VAR ( opline - > result . var ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-04-30 22:32:42 +08:00
fast_is_smaller_function ( result ,
2014-04-22 03:30:19 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
2014-04-30 22:32:42 +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 ;
2014-02-10 14:04:30 +08:00
zval * result = EX_VAR ( opline - > result . var ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-04-30 22:32:42 +08:00
fast_is_smaller_or_equal_function ( result ,
2014-04-22 03:30:19 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
2014-04-30 22:32:42 +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 ( ) ;
2014-02-10 14:04:30 +08:00
bitwise_or_function ( EX_VAR ( opline - > result . var ) ,
2014-02-18 20:27:38 +08:00
GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR_DEREF ( 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 ( 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 ( ) ;
2014-02-10 14:04:30 +08:00
bitwise_and_function ( EX_VAR ( opline - > result . var ) ,
2014-02-18 20:27:38 +08:00
GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR_DEREF ( 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 ( 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 ( ) ;
2014-02-10 14:04:30 +08:00
bitwise_xor_function ( EX_VAR ( opline - > result . var ) ,
2014-02-18 20:27:38 +08:00
GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR_DEREF ( 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 ( 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 ( ) ;
2014-02-10 14:04:30 +08:00
boolean_xor_function ( EX_VAR ( opline - > result . var ) ,
2014-02-18 20:27:38 +08:00
GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR_DEREF ( 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 ( 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 ( ) ;
2014-02-10 14:04:30 +08:00
bitwise_not_function ( EX_VAR ( opline - > result . var ) ,
2014-02-18 20:27:38 +08:00
GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) TSRMLS_CC ) ;
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 ( 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 ( ) ;
2014-02-10 14:04:30 +08:00
boolean_not_function ( EX_VAR ( opline - > result . var ) ,
2014-02-18 20:27:38 +08:00
GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) TSRMLS_CC ) ;
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-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 ;
2014-03-04 16:27:50 +08:00
zval * object = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
2004-10-23 05:42:14 +08:00
zval * property = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2014-03-05 19:33:31 +08:00
zval * value ;
2004-10-23 05:42:14 +08:00
int have_get_ptr = 0 ;
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( object ) = = IS_STR_OFFSET ) ) {
2009-03-18 20:53:17 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an object " ) ;
}
2014-04-04 06:52:53 +08:00
object = make_real_object ( object TSRMLS_CC ) ;
2014-03-14 02:56:18 +08:00
2014-03-05 19:33:31 +08:00
value = get_zval_ptr ( ( opline + 1 ) - > op1_type , & ( opline + 1 ) - > op1 , execute_data , & free_op_data1 , BP_VAR_R ) ;
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 ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
2004-10-23 05:42:14 +08:00
}
} else {
/* here we are sure we are dealing with an object */
if ( opline - > extended_value = = ZEND_ASSIGN_OBJ
& & Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ) {
2014-04-17 20:10:16 +08:00
zval * zptr = Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ( object , property , BP_VAR_RW , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( property ) : - 1 ) 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 ;
2014-02-10 14:04:30 +08:00
binary_op ( zptr , zptr , value TSRMLS_CC ) ;
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , zptr ) ;
2004-10-23 05:42:14 +08:00
}
}
}
if ( ! have_get_ptr ) {
2005-04-16 01:15:18 +08:00
zval * z = NULL ;
2014-02-27 19:40:13 +08:00
zval rv ;
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 ) {
2014-04-17 20:10:16 +08:00
z = Z_OBJ_HT_P ( object ) - > read_property ( object , property , BP_VAR_R , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( property ) : - 1 ) , & rv 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 ) {
2014-02-27 19:40:13 +08:00
z = Z_OBJ_HT_P ( object ) - > read_dimension ( object , property , BP_VAR_R , & rv TSRMLS_CC ) ;
2009-03-18 20:53:17 +08:00
}
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 ) {
2014-04-15 11:05:03 +08:00
zval rv ;
zval * value = Z_OBJ_HT_P ( z ) - > get ( z , & rv TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2007-10-07 13:22:07 +08:00
if ( Z_REFCOUNT_P ( z ) = = 0 ) {
2005-04-16 01:15:18 +08:00
zval_dtor ( z ) ;
}
2014-04-15 11:05:03 +08:00
ZVAL_COPY_VALUE ( z , value ) ;
2005-04-16 01:15:18 +08:00
}
2014-03-07 04:26:21 +08:00
//??? if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
2014-02-10 14:04:30 +08:00
SEPARATE_ZVAL_IF_NOT_REF ( z ) ;
2005-04-16 01:15:18 +08:00
binary_op ( z , z , value TSRMLS_CC ) ;
2009-03-18 20:53:17 +08:00
if ( opline - > extended_value = = ZEND_ASSIGN_OBJ ) {
2014-04-17 20:10:16 +08:00
Z_OBJ_HT_P ( object ) - > write_property ( object , property , z , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( property ) : - 1 ) 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 ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , z ) ;
2005-04-16 01:15:18 +08:00
}
2014-02-10 14:04:30 +08:00
zval_ptr_dtor ( z ) ;
2005-04-16 01:15:18 +08:00
} 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 ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
2004-10-23 05:42:14 +08:00
}
}
}
2014-04-16 01:56:30 +08:00
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 ( ) ;
}
2014-04-08 06:25:49 +08:00
ZEND_VM_HELPER_EX ( zend_binary_assign_op_dim_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 ;
2014-02-10 14:04:30 +08:00
zval * var_ptr ;
2014-04-08 06:25:49 +08:00
zval * value , * container ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-04-08 06:25:49 +08:00
container = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( container ) = = IS_STR_OFFSET ) ) {
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an array " ) ;
} else if ( UNEXPECTED ( Z_TYPE_P ( container ) = = IS_OBJECT ) ) {
if ( OP1_TYPE = = IS_VAR & & ! OP1_FREE ) {
Z_ADDREF_P ( container ) ; /* undo the effect of get_obj_zval_ptr_ptr() */
}
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_obj_helper , binary_op , binary_op ) ;
} else {
zval * dim = GET_OP2_ZVAL_PTR_DEREF ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2014-04-08 06:25:49 +08:00
zend_fetch_dimension_address_RW ( EX_VAR ( ( opline + 1 ) - > op2 . var ) , container , dim , OP2_TYPE TSRMLS_CC ) ;
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
}
2014-02-10 14:04:30 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_STR_OFFSET ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use assign-op operators with overloaded objects nor string offsets " ) ;
}
2014-02-10 14:04:30 +08:00
if ( UNEXPECTED ( var_ptr = = & EG ( error_zval ) ) ) {
2014-04-08 06:25:49 +08:00
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
2004-10-23 05:42:14 +08:00
}
2014-04-08 06:25:49 +08:00
ZEND_VM_C_GOTO ( assign_op_dim_exit ) ;
2004-10-23 05:42:14 +08:00
}
2014-06-12 07:14:57 +08:00
ZVAL_DEREF ( var_ptr ) ;
SEPARATE_ZVAL_NOREF ( var_ptr ) ;
2004-10-23 05:42:14 +08:00
2014-04-08 06:25:49 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_OBJECT ) & &
UNEXPECTED ( Z_OBJ_HANDLER_P ( var_ptr , get ) & & Z_OBJ_HANDLER_P ( var_ptr , set ) ) ) {
2004-10-23 05:42:14 +08:00
/* proxy object */
2014-04-15 11:05:03 +08:00
zval rv ;
zval * objval = Z_OBJ_HANDLER_P ( var_ptr , get ) ( var_ptr , & rv 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 ) ;
2014-02-10 14:04:30 +08:00
Z_OBJ_HANDLER_P ( var_ptr , set ) ( var_ptr , objval TSRMLS_CC ) ;
zval_ptr_dtor ( objval ) ;
2004-10-23 05:42:14 +08:00
} else {
2014-02-10 14:04:30 +08:00
binary_op ( var_ptr , var_ptr , value TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
}
2014-04-08 06:25:49 +08:00
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , var_ptr ) ;
2004-10-23 05:42:14 +08:00
}
2014-04-08 06:25:49 +08:00
ZEND_VM_C_LABEL ( assign_op_dim_exit ) :
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2014-04-08 06:25:49 +08:00
FREE_OP ( free_op_data1 ) ;
FREE_OP_VAR_PTR ( free_op_data2 ) ;
FREE_OP1_VAR_PTR ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_INC_OPCODE ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
2014-04-08 06:25:49 +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 ) )
{
USE_OPLINE
zend_free_op free_op1 , free_op2 ;
zval * var_ptr ;
zval * value ;
SAVE_OPLINE ( ) ;
value = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
var_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_STR_OFFSET ) ) {
zend_error_noreturn ( E_ERROR , " Cannot use assign-op operators with overloaded objects nor string offsets " ) ;
}
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( var_ptr = = & EG ( error_zval ) ) ) {
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
}
ZEND_VM_C_GOTO ( assign_op_exit ) ;
}
2014-06-12 07:14:57 +08:00
ZVAL_DEREF ( var_ptr ) ;
SEPARATE_ZVAL_NOREF ( var_ptr ) ;
2014-04-08 06:25:49 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_OBJECT ) & &
UNEXPECTED ( Z_OBJ_HANDLER_P ( var_ptr , get ) & & Z_OBJ_HANDLER_P ( var_ptr , set ) ) ) {
/* proxy object */
2014-04-15 11:05:03 +08:00
zval rv ;
zval * objval = Z_OBJ_HANDLER_P ( var_ptr , get ) ( var_ptr , & rv TSRMLS_CC ) ;
2014-04-08 06:25:49 +08:00
Z_ADDREF_P ( objval ) ;
binary_op ( objval , objval , value TSRMLS_CC ) ;
Z_OBJ_HANDLER_P ( var_ptr , set ) ( var_ptr , objval TSRMLS_CC ) ;
zval_ptr_dtor ( objval ) ;
2010-04-20 19:16:39 +08:00
} else {
2014-04-08 06:25:49 +08:00
binary_op ( var_ptr , var_ptr , value TSRMLS_CC ) ;
}
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , var_ptr ) ;
2004-10-23 05:42:14 +08:00
}
2014-04-08 06:25:49 +08:00
ZEND_VM_C_LABEL ( assign_op_exit ) :
FREE_OP2 ( ) ;
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
{
2014-04-08 06:25:49 +08:00
USE_OPLINE
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , add_function ) ;
} else if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , add_function ) ;
2014-04-22 17:11:07 +08:00
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
2014-04-08 06:25:49 +08:00
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_obj_helper , binary_op , add_function ) ;
}
2004-10-23 05:42:14 +08:00
}
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
{
2014-04-08 06:25:49 +08:00
USE_OPLINE
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , sub_function ) ;
} else if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , sub_function ) ;
2014-04-22 17:11:07 +08:00
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
2014-04-08 06:25:49 +08:00
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_obj_helper , binary_op , sub_function ) ;
}
2004-10-23 05:42:14 +08:00
}
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
{
2014-04-08 06:25:49 +08:00
USE_OPLINE
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , mul_function ) ;
} else if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , mul_function ) ;
2014-04-22 17:11:07 +08:00
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
2014-04-08 06:25:49 +08:00
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_obj_helper , binary_op , mul_function ) ;
}
2004-10-23 05:42:14 +08:00
}
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
{
2014-04-08 06:25:49 +08:00
USE_OPLINE
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , div_function ) ;
} else if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , div_function ) ;
2014-04-22 17:11:07 +08:00
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
2014-04-08 06:25:49 +08:00
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_obj_helper , binary_op , div_function ) ;
}
2004-10-23 05:42:14 +08:00
}
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
{
2014-04-08 06:25:49 +08:00
USE_OPLINE
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , mod_function ) ;
} else if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , mod_function ) ;
2014-04-22 17:11:07 +08:00
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
2014-04-08 06:25:49 +08:00
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_obj_helper , binary_op , mod_function ) ;
}
2004-10-23 05:42:14 +08:00
}
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
{
2014-04-08 06:25:49 +08:00
USE_OPLINE
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , shift_left_function ) ;
} else if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , shift_left_function ) ;
2014-04-22 17:11:07 +08:00
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
2014-04-08 06:25:49 +08:00
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_obj_helper , binary_op , shift_left_function ) ;
}
2004-10-23 05:42:14 +08:00
}
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
{
2014-04-08 06:25:49 +08:00
USE_OPLINE
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , shift_right_function ) ;
} else if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , shift_right_function ) ;
2014-04-22 17:11:07 +08:00
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
2014-04-08 06:25:49 +08:00
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_obj_helper , binary_op , shift_right_function ) ;
}
2004-10-23 05:42:14 +08:00
}
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
{
2014-04-08 06:25:49 +08:00
USE_OPLINE
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , concat_function ) ;
} else if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , concat_function ) ;
2014-04-22 17:11:07 +08:00
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
2014-04-08 06:25:49 +08:00
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_obj_helper , binary_op , concat_function ) ;
}
2004-10-23 05:42:14 +08:00
}
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
{
2014-04-08 06:25:49 +08:00
USE_OPLINE
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , bitwise_or_function ) ;
} else if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , bitwise_or_function ) ;
2014-04-22 17:11:07 +08:00
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
2014-04-08 06:25:49 +08:00
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_obj_helper , binary_op , bitwise_or_function ) ;
}
2004-10-23 05:42:14 +08:00
}
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
{
2014-04-08 06:25:49 +08:00
USE_OPLINE
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , bitwise_and_function ) ;
} else if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , bitwise_and_function ) ;
2014-04-22 17:11:07 +08:00
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
2014-04-08 06:25:49 +08:00
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_obj_helper , binary_op , bitwise_and_function ) ;
}
2004-10-23 05:42:14 +08:00
}
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
{
2014-04-08 06:25:49 +08:00
USE_OPLINE
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , bitwise_xor_function ) ;
} else if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , bitwise_xor_function ) ;
2014-04-22 17:11:07 +08:00
} else /* if (EXPECTED(opline->extended_value == ZEND_ASSIGN_OBJ)) */ {
2014-04-08 06:25:49 +08:00
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_obj_helper , binary_op , bitwise_xor_function ) ;
}
2004-10-23 05:42:14 +08:00
}
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 ;
zval * object ;
2010-04-20 19:16:39 +08:00
zval * property ;
2014-02-10 14:04:30 +08:00
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 ( ) ;
2014-03-04 16:27:50 +08:00
object = 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 ) ;
2014-02-10 14:04:30 +08:00
retval = EX_VAR ( opline - > result . var ) ;
2010-04-20 19:16:39 +08:00
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( object ) = = IS_STR_OFFSET ) ) {
2009-03-18 20:53:17 +08:00
zend_error_noreturn ( E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
}
2014-04-04 06:52:53 +08:00
object = make_real_object ( object TSRMLS_CC ) ; /* this should modify object only if it's empty */
2004-10-23 05:42:14 +08:00
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 ) ) {
2014-02-10 14:04:30 +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 */
if ( Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ) {
2014-04-17 20:10:16 +08:00
zval * zptr = Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ( object , property , BP_VAR_RW , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( property ) : - 1 ) 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 ;
2014-02-10 14:04:30 +08:00
incdec_op ( zptr ) ;
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_COPY ( retval , zptr ) ;
2004-10-23 05:42:14 +08:00
}
}
}
if ( ! have_get_ptr ) {
2014-02-27 19:40:13 +08:00
zval rv ;
2005-04-16 01:15:18 +08:00
if ( Z_OBJ_HT_P ( object ) - > read_property & & Z_OBJ_HT_P ( object ) - > write_property ) {
2014-04-17 20:10:16 +08:00
zval * z = Z_OBJ_HT_P ( object ) - > read_property ( object , property , BP_VAR_R , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( property ) : - 1 ) , & rv 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 ) {
2014-04-15 11:05:03 +08:00
zval rv ;
zval * value = Z_OBJ_HT_P ( z ) - > get ( z , & rv TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2007-10-07 13:22:07 +08:00
if ( Z_REFCOUNT_P ( z ) = = 0 ) {
2005-04-16 01:15:18 +08:00
zval_dtor ( z ) ;
}
2014-04-15 11:05:03 +08:00
ZVAL_COPY_VALUE ( z , value ) ;
2005-04-16 01:15:18 +08:00
}
2014-02-28 03:25:41 +08:00
if ( Z_REFCOUNTED_P ( z ) ) Z_ADDREF_P ( z ) ;
2014-02-10 14:04:30 +08:00
SEPARATE_ZVAL_IF_NOT_REF ( z ) ;
2005-04-16 01:15:18 +08:00
incdec_op ( z ) ;
2014-02-10 14:04:30 +08:00
ZVAL_COPY_VALUE ( retval , z ) ;
2014-04-17 20:10:16 +08:00
Z_OBJ_HT_P ( object ) - > write_property ( object , property , z , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( property ) : - 1 ) TSRMLS_CC ) ;
2014-02-10 14:04:30 +08:00
SELECTIVE_PZVAL_LOCK ( retval , opline ) ;
zval_ptr_dtor ( z ) ;
2005-04-16 01:15:18 +08:00
} 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 ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( retval ) ;
2004-10-23 05:42:14 +08:00
}
}
}
2014-04-16 01:56:30 +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 ( 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 ;
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 ( ) ;
2014-03-04 16:27:50 +08:00
object = 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 ) ;
2014-02-10 14:04:30 +08:00
retval = EX_VAR ( opline - > result . var ) ;
2010-04-20 19:16:39 +08:00
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( object ) = = IS_STR_OFFSET ) ) {
2009-03-18 20:53:17 +08:00
zend_error_noreturn ( E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
}
2014-04-04 06:52:53 +08:00
object = make_real_object ( object TSRMLS_CC ) ; /* this should modify object only if it's empty */
2004-10-23 05:42:14 +08:00
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 */
if ( Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ) {
2014-04-17 20:10:16 +08:00
zval * zptr = Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ( object , property , BP_VAR_RW , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( property ) : - 1 ) 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 ) ;
2014-02-10 14:04:30 +08:00
ZVAL_DUP ( retval , zptr ) ;
2004-10-23 05:42:14 +08:00
2014-02-10 14:04:30 +08:00
incdec_op ( zptr ) ;
2004-10-23 05:42:14 +08:00
}
}
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 ) {
2014-02-27 19:40:13 +08:00
zval rv ;
2014-04-17 20:10:16 +08:00
zval * z = Z_OBJ_HT_P ( object ) - > read_property ( object , property , BP_VAR_R , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( property ) : - 1 ) , & rv TSRMLS_CC ) ;
2014-02-10 14:04:30 +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 ) {
2014-04-15 11:05:03 +08:00
zval rv ;
zval * value = Z_OBJ_HT_P ( z ) - > get ( z , & rv TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2007-10-07 13:22:07 +08:00
if ( Z_REFCOUNT_P ( z ) = = 0 ) {
2005-04-16 01:15:18 +08:00
zval_dtor ( z ) ;
}
2014-04-15 11:05:03 +08:00
ZVAL_COPY_VALUE ( z , value ) ;
2004-10-23 05:42:14 +08:00
}
2014-02-10 14:04:30 +08:00
ZVAL_DUP ( retval , z ) ;
ZVAL_DUP ( & z_copy , z ) ;
incdec_op ( & z_copy ) ;
2014-02-28 03:25:41 +08:00
if ( Z_REFCOUNTED_P ( z ) ) Z_ADDREF_P ( z ) ;
2014-04-17 20:10:16 +08:00
Z_OBJ_HT_P ( object ) - > write_property ( object , property , & z_copy , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( property ) : - 1 ) TSRMLS_CC ) ;
2005-04-26 21:23:23 +08:00
zval_ptr_dtor ( & z_copy ) ;
2014-02-10 14:04:30 +08:00
zval_ptr_dtor ( z ) ;
2005-04-16 01:15:18 +08:00
} 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
}
}
2014-04-16 01:56:30 +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 ( 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 ;
2014-02-10 14:04:30 +08:00
zval * var_ptr ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-03-04 16:27:50 +08:00
var_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
2010-04-20 19:16:39 +08:00
2014-04-22 01:38:44 +08:00
if ( EXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_LONG ) ) {
fast_increment_function ( var_ptr ) ;
if ( RETURN_VALUE_USED ( opline ) ) {
ZVAL_COPY_VALUE ( EX_VAR ( opline - > result . var ) , var_ptr ) ;
}
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_STR_OFFSET ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
}
2014-02-10 14:04:30 +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 ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( EX_VAR ( opline - > result . 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 ( ) ;
}
2014-06-12 07:14:57 +08:00
ZVAL_DEREF ( var_ptr ) ;
SEPARATE_ZVAL_NOREF ( var_ptr ) ;
2004-10-23 05:42:14 +08:00
2014-02-10 14:04:30 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_OBJECT )
& & Z_OBJ_HANDLER_P ( var_ptr , get )
& & Z_OBJ_HANDLER_P ( var_ptr , set ) ) {
2004-10-23 05:42:14 +08:00
/* proxy object */
2014-04-15 11:05:03 +08:00
zval rv ;
zval * val = Z_OBJ_HANDLER_P ( var_ptr , get ) ( var_ptr , & rv 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 ) ;
2014-02-10 14:04:30 +08:00
Z_OBJ_HANDLER_P ( var_ptr , set ) ( var_ptr , val TSRMLS_CC ) ;
zval_ptr_dtor ( val ) ;
2004-10-23 05:42:14 +08:00
} else {
2014-04-22 01:38:44 +08:00
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 ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_COPY ( EX_VAR ( 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 ;
2014-02-10 14:04:30 +08:00
zval * var_ptr ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-03-04 16:27:50 +08:00
var_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
2010-04-20 19:16:39 +08:00
2014-04-22 01:38:44 +08:00
if ( EXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_LONG ) ) {
fast_decrement_function ( var_ptr ) ;
if ( RETURN_VALUE_USED ( opline ) ) {
ZVAL_COPY_VALUE ( EX_VAR ( opline - > result . var ) , var_ptr ) ;
}
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_STR_OFFSET ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
}
2014-02-10 14:04:30 +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 ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( EX_VAR ( opline - > result . 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 ( ) ;
}
2014-06-12 07:14:57 +08:00
ZVAL_DEREF ( var_ptr ) ;
SEPARATE_ZVAL_NOREF ( var_ptr ) ;
2004-10-23 05:42:14 +08:00
2014-02-10 14:04:30 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_OBJECT )
& & Z_OBJ_HANDLER_P ( var_ptr , get )
& & Z_OBJ_HANDLER_P ( var_ptr , set ) ) {
2004-10-23 05:42:14 +08:00
/* proxy object */
2014-04-15 11:05:03 +08:00
zval rv ;
zval * val = Z_OBJ_HANDLER_P ( var_ptr , get ) ( var_ptr , & rv 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 ) ;
2014-02-10 14:04:30 +08:00
Z_OBJ_HANDLER_P ( var_ptr , set ) ( var_ptr , val TSRMLS_CC ) ;
zval_ptr_dtor ( val ) ;
2004-10-23 05:42:14 +08:00
} else {
2014-04-22 01:38:44 +08:00
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 ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_COPY ( EX_VAR ( 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 ;
2014-02-10 14:04:30 +08:00
zval * var_ptr , * retval ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-03-04 16:27:50 +08:00
var_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
2004-10-23 05:42:14 +08:00
2014-04-22 01:38:44 +08:00
if ( EXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_LONG ) ) {
ZVAL_COPY_VALUE ( EX_VAR ( opline - > result . var ) , var_ptr ) ;
fast_increment_function ( var_ptr ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_STR_OFFSET ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
}
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( var_ptr = = & EG ( error_zval ) ) ) {
ZVAL_NULL ( EX_VAR ( opline - > result . 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 ( ) ;
}
2014-02-10 14:04:30 +08:00
retval = EX_VAR ( opline - > result . var ) ;
2004-10-23 05:42:14 +08:00
2014-03-27 17:39:09 +08:00
if ( UNEXPECTED ( Z_ISREF_P ( var_ptr ) ) ) {
2014-02-24 15:23:25 +08:00
var_ptr = Z_REFVAL_P ( var_ptr ) ;
2014-02-25 17:20:43 +08:00
ZVAL_DUP ( retval , var_ptr ) ;
2014-02-24 15:23:25 +08:00
} else {
2014-02-25 17:20:43 +08:00
ZVAL_DUP ( retval , var_ptr ) ;
2014-06-05 20:04:11 +08:00
SEPARATE_ZVAL_NOREF ( var_ptr ) ;
2014-02-24 15:23:25 +08:00
}
2004-10-23 05:42:14 +08:00
2014-02-10 14:04:30 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_OBJECT )
& & Z_OBJ_HANDLER_P ( var_ptr , get )
& & Z_OBJ_HANDLER_P ( var_ptr , set ) ) {
2004-10-23 05:42:14 +08:00
/* proxy object */
2014-04-15 11:05:03 +08:00
zval rv ;
zval * val = Z_OBJ_HANDLER_P ( var_ptr , get ) ( var_ptr , & rv 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 ) ;
2014-02-10 14:04:30 +08:00
Z_OBJ_HANDLER_P ( var_ptr , set ) ( var_ptr , val TSRMLS_CC ) ;
zval_ptr_dtor ( val ) ;
2004-10-23 05:42:14 +08:00
} else {
2014-04-22 01:38:44 +08:00
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 ;
2014-02-10 14:04:30 +08:00
zval * var_ptr , * retval ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-03-04 16:27:50 +08:00
var_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
2010-04-20 19:16:39 +08:00
2014-04-22 01:38:44 +08:00
if ( EXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_LONG ) ) {
ZVAL_COPY_VALUE ( EX_VAR ( opline - > result . var ) , var_ptr ) ;
fast_decrement_function ( var_ptr ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_STR_OFFSET ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
}
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( var_ptr = = & EG ( error_zval ) ) ) {
ZVAL_NULL ( EX_VAR ( opline - > result . 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 ( ) ;
}
2014-02-10 14:04:30 +08:00
retval = EX_VAR ( opline - > result . var ) ;
2004-10-23 05:42:14 +08:00
2014-03-27 17:39:09 +08:00
if ( UNEXPECTED ( Z_ISREF_P ( var_ptr ) ) ) {
2014-02-24 15:23:25 +08:00
var_ptr = Z_REFVAL_P ( var_ptr ) ;
2014-02-25 17:20:43 +08:00
ZVAL_DUP ( retval , var_ptr ) ;
2014-02-24 15:23:25 +08:00
} else {
2014-02-25 17:20:43 +08:00
ZVAL_DUP ( retval , var_ptr ) ;
2014-06-05 20:04:11 +08:00
SEPARATE_ZVAL_NOREF ( var_ptr ) ;
2014-02-24 15:23:25 +08:00
}
2004-10-23 05:42:14 +08:00
2014-02-10 14:04:30 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_OBJECT )
& & Z_OBJ_HANDLER_P ( var_ptr , get )
& & Z_OBJ_HANDLER_P ( var_ptr , set ) ) {
2004-10-23 05:42:14 +08:00
/* proxy object */
2014-04-15 11:05:03 +08:00
zval rv ;
zval * val = Z_OBJ_HANDLER_P ( var_ptr , get ) ( var_ptr , & rv 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 ) ;
2014-02-10 14:04:30 +08:00
Z_OBJ_HANDLER_P ( var_ptr , set ) ( var_ptr , val TSRMLS_CC ) ;
zval_ptr_dtor ( val ) ;
2004-10-23 05:42:14 +08:00
} else {
2014-04-22 01:38:44 +08:00
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 ;
2010-04-20 19:16:39 +08:00
zval * z ;
SAVE_OPLINE ( ) ;
2014-03-27 17:39:09 +08:00
z = GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ;
2014-02-23 19:36:38 +08:00
2014-04-21 23:12:10 +08:00
zend_print_variable ( z TSRMLS_CC ) ;
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 ( 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
2014-02-10 14:04:30 +08:00
ZVAL_LONG ( EX_VAR ( opline - > result . 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 ;
2014-02-10 14:04:30 +08:00
zval * retval ;
2014-06-03 04:36:31 +08:00
zend_string * name ;
2004-10-23 05:42:14 +08:00
HashTable * target_symbol_table ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
varname = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-06-03 04:36:31 +08:00
if ( OP1_TYPE = = IS_CONST ) {
name = Z_STR_P ( varname ) ;
} else if ( EXPECTED ( Z_TYPE_P ( varname ) = = IS_STRING ) ) {
name = Z_STR_P ( varname ) ;
STR_ADDREF ( name ) ;
} else {
name = zval_get_string ( 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 ) {
2014-04-17 19:40:45 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ) {
ce = CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-04-17 19:40:45 +08:00
ce = zend_fetch_class_by_name ( Z_STR_P ( opline - > op2 . zv ) , opline - > op2 . zv + 1 , 0 TSRMLS_CC ) ;
2012-02-25 21:56:59 +08:00
if ( UNEXPECTED ( ce = = NULL ) ) {
2014-04-08 04:38:54 +08:00
if ( OP1_TYPE ! = IS_CONST ) {
2014-06-03 04:36:31 +08:00
STR_RELEASE ( name ) ;
2012-02-25 21:56:59 +08:00
}
FREE_OP1 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-04-17 19:40:45 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) , ce ) ;
2010-05-24 22:11:39 +08:00
}
2010-05-06 18:27:35 +08:00
} else {
2014-02-10 14:04:30 +08:00
ce = Z_CE_P ( EX_VAR ( opline - > op2 . var ) ) ;
2010-05-06 18:27:35 +08:00
}
2014-06-03 04:36:31 +08:00
retval = zend_std_get_static_property ( ce , name , 0 , ( ( OP1_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( varname ) : - 1 ) TSRMLS_CC ) ;
2009-09-21 21:01:17 +08:00
FREE_OP1 ( ) ;
2004-10-23 05:42:14 +08:00
} else {
2014-07-03 02:03:21 +08:00
target_symbol_table = zend_get_target_symbol_table ( execute_data , opline - > extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC ) ;
2014-06-03 04:36:31 +08:00
retval = zend_hash_find ( target_symbol_table , name ) ;
2014-04-08 04:38:54 +08:00
if ( retval = = NULL ) {
2004-10-23 05:42:14 +08:00
switch ( type ) {
case BP_VAR_R :
case BP_VAR_UNSET :
2014-06-03 04:36:31 +08:00
zend_error ( E_NOTICE , " Undefined variable: %s " , name - > val ) ;
2004-10-23 05:42:14 +08:00
/* break missing intentionally */
case BP_VAR_IS :
2014-03-04 16:27:50 +08:00
retval = EX_VAR ( opline - > result . var ) ;
ZVAL_NULL ( retval ) ;
2004-10-23 05:42:14 +08:00
break ;
case BP_VAR_RW :
2014-06-03 04:36:31 +08:00
zend_error ( E_NOTICE , " Undefined variable: %s " , name - > val ) ;
2004-10-23 05:42:14 +08:00
/* break missing intentionally */
2014-03-11 14:23:14 +08:00
case BP_VAR_W :
2014-06-03 04:36:31 +08:00
retval = zend_hash_add_new ( target_symbol_table , name , & EG ( uninitialized_zval ) ) ;
2004-10-23 05:42:14 +08:00
break ;
EMPTY_SWITCH_DEFAULT_CASE ( )
}
2014-04-04 23:01:53 +08:00
/* GLOBAL or $$name variable may be an INDIRECT pointer to CV */
2014-04-16 05:45:40 +08:00
} else if ( Z_TYPE_P ( retval ) = = IS_INDIRECT ) {
2014-03-26 22:07:31 +08:00
retval = Z_INDIRECT_P ( retval ) ;
if ( Z_TYPE_P ( retval ) = = IS_UNDEF ) {
switch ( type ) {
case BP_VAR_R :
case BP_VAR_UNSET :
2014-06-03 04:36:31 +08:00
zend_error ( E_NOTICE , " Undefined variable: %s " , name - > val ) ;
2014-03-26 22:07:31 +08:00
/* break missing intentionally */
case BP_VAR_IS :
retval = EX_VAR ( opline - > result . var ) ;
ZVAL_NULL ( retval ) ;
break ;
case BP_VAR_RW :
2014-06-03 04:36:31 +08:00
zend_error ( E_NOTICE , " Undefined variable: %s " , name - > val ) ;
2014-03-26 22:07:31 +08:00
/* break missing intentionally */
case BP_VAR_W :
ZVAL_NULL ( retval ) ;
break ;
EMPTY_SWITCH_DEFAULT_CASE ( )
}
}
2004-10-23 05:42:14 +08:00
}
2014-04-08 04:38:54 +08:00
if ( ( opline - > extended_value & ZEND_FETCH_TYPE_MASK ) = = ZEND_FETCH_STATIC ) {
2014-06-17 03:32:58 +08:00
if ( Z_CONSTANT_P ( retval ) ) {
zval_update_constant ( retval , 1 TSRMLS_CC ) ;
}
2014-04-08 04:38:54 +08:00
} else if ( ( opline - > extended_value & ZEND_FETCH_TYPE_MASK ) ! = ZEND_FETCH_GLOBAL_LOCK ) {
FREE_OP1 ( ) ;
2014-03-11 14:23:14 +08:00
}
2004-10-23 05:42:14 +08:00
}
2014-04-08 04:38:54 +08:00
if ( OP1_TYPE ! = IS_CONST ) {
2014-06-03 04:36:31 +08:00
STR_RELEASE ( name ) ;
2004-10-23 05:42:14 +08:00
}
2014-02-21 21:39:02 +08:00
2014-04-08 04:38:54 +08:00
ZEND_ASSERT ( retval ! = NULL ) ;
if ( type = = BP_VAR_R | | type = = BP_VAR_IS ) {
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , retval ) ;
} else {
if ( /*type == BP_VAR_W &&*/ ( opline - > extended_value & ZEND_FETCH_MAKE_REF ) ) {
2014-06-05 20:04:11 +08:00
ZVAL_MAKE_REF ( retval ) ;
2014-04-08 04:38:54 +08:00
}
ZVAL_INDIRECT ( EX_VAR ( opline - > result . var ) , retval ) ;
2014-02-19 19:34:32 +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
2014-04-08 04:38:54 +08:00
if ( zend_is_by_ref_func_arg_fetch ( opline , EX ( call ) TSRMLS_CC ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_fetch_var_address_helper , type , BP_VAR_W ) ;
} else {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_fetch_var_address_helper , type , 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 ;
2013-11-27 18:26:34 +08:00
zval * container ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2013-11-27 18:26:34 +08:00
container = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-04-11 19:05:12 +08:00
zend_fetch_dimension_address_read_R ( EX_VAR ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR_DEREF ( BP_VAR_R ) , OP2_TYPE TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2013-11-27 18:56:18 +08:00
if ( OP1_TYPE ! = IS_VAR | | ! ( opline - > extended_value & ZEND_FETCH_ADD_LOCK ) ) {
2012-08-14 08:59:40 +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 ( 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 ;
2014-02-10 14:04:30 +08:00
zval * container ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-03-04 16:27:50 +08:00
container = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2010-04-20 19:16:39 +08:00
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( container ) = = IS_STR_OFFSET ) ) {
2008-01-24 01:55:55 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an array " ) ;
}
2014-04-05 05:56:51 +08:00
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
2014-04-11 19:05:12 +08:00
zend_fetch_dimension_address_W ( EX_VAR ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR_DEREF ( BP_VAR_R ) , OP2_TYPE TSRMLS_CC ) ;
2014-04-05 05:56:51 +08:00
} else {
2014-04-11 19:05:12 +08:00
zend_fetch_dimension_address_W_ref ( EX_VAR ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR_DEREF ( BP_VAR_R ) , OP2_TYPE TSRMLS_CC ) ;
2014-04-05 05:56:51 +08:00
}
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2014-03-04 21:23:23 +08:00
if ( OP1_TYPE = = IS_VAR & & OP1_FREE & & READY_TO_DESTROY ( free_op1 . var ) ) {
EXTRACT_ZVAL_PTR ( EX_VAR ( opline - > result . var ) ) ;
}
2014-03-04 16:27:50 +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 ( ) ;
}
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 ;
2014-02-10 14:04:30 +08:00
zval * container ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-03-06 21:59:17 +08:00
container = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
2004-10-23 05:42:14 +08:00
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( container ) = = IS_STR_OFFSET ) ) {
2008-01-24 01:55:55 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an array " ) ;
}
2014-04-11 19:05:12 +08:00
zend_fetch_dimension_address_RW ( EX_VAR ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR_DEREF ( BP_VAR_R ) , OP2_TYPE TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2014-03-04 21:23:23 +08:00
if ( OP1_TYPE = = IS_VAR & & OP1_FREE & & READY_TO_DESTROY ( free_op1 . var ) ) {
EXTRACT_ZVAL_PTR ( EX_VAR ( opline - > result . 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 ( ) ;
}
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 ;
2013-11-27 18:26:34 +08:00
zval * container ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2013-11-27 18:26:34 +08:00
container = GET_OP1_ZVAL_PTR ( BP_VAR_IS ) ;
2014-04-11 19:05:12 +08:00
zend_fetch_dimension_address_read_IS ( EX_VAR ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR_DEREF ( BP_VAR_R ) , OP2_TYPE TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2013-11-27 18:26:34 +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-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
2014-02-10 14:04:30 +08:00
zval * container ;
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2006-05-12 05:07:39 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2013-08-29 17:35:11 +08:00
if ( zend_is_by_ref_func_arg_fetch ( opline , EX ( call ) TSRMLS_CC ) ) {
2014-03-04 16:27:50 +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 " ) ;
}
2014-04-11 19:05:12 +08:00
zend_fetch_dimension_address_W ( EX_VAR ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR_DEREF ( BP_VAR_R ) , OP2_TYPE TSRMLS_CC ) ;
2014-03-04 21:23:23 +08:00
if ( OP1_TYPE = = IS_VAR & & OP1_FREE & & READY_TO_DESTROY ( free_op1 . var ) ) {
EXTRACT_ZVAL_PTR ( EX_VAR ( opline - > result . var ) ) ;
}
2013-05-17 17:15:09 +08:00
FREE_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
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
}
2013-11-27 18:26:34 +08:00
container = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-04-11 19:05:12 +08:00
zend_fetch_dimension_address_read_R ( EX_VAR ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR_DEREF ( BP_VAR_R ) , OP2_TYPE TSRMLS_CC ) ;
2013-05-17 17:15:09 +08:00
FREE_OP2 ( ) ;
2013-11-27 18:26:34 +08:00
FREE_OP1 ( ) ;
2006-07-19 17:55:19 +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 ( 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 ;
2014-02-10 14:04:30 +08:00
zval * container ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-03-04 16:27:50 +08:00
container = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_UNSET ) ;
2004-10-23 05:42:14 +08:00
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( container ) = = IS_STR_OFFSET ) ) {
2008-01-24 01:55:55 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an array " ) ;
}
2014-04-11 19:05:12 +08:00
zend_fetch_dimension_address_UNSET ( EX_VAR ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR_DEREF ( BP_VAR_R ) , OP2_TYPE TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2014-03-04 21:23:23 +08:00
if ( OP1_TYPE = = IS_VAR & & OP1_FREE & & READY_TO_DESTROY ( free_op1 . var ) ) {
EXTRACT_ZVAL_PTR ( EX_VAR ( opline - > result . var ) ) ;
}
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
2014-04-04 23:01:53 +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 ( ) ;
2014-03-27 17:39:09 +08:00
container = GET_OP1_OBJ_ZVAL_PTR_DEREF ( BP_VAR_R ) ;
2010-04-20 19:16:39 +08:00
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 " ) ;
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
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
/* here we are sure we are dealing with an object */
2014-04-17 20:10:16 +08:00
retval = Z_OBJ_HT_P ( container ) - > read_property ( container , offset , BP_VAR_R , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( offset ) : - 1 ) , EX_VAR ( opline - > result . var ) TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2014-02-27 19:40:13 +08:00
if ( retval ! = EX_VAR ( opline - > result . var ) ) {
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , retval ) ;
}
2004-10-23 05:42:14 +08:00
}
2014-04-16 01:56:30 +08:00
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 ;
2014-02-10 14:04:30 +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 ) ;
2014-03-04 16:27:50 +08:00
container = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( container ) = = IS_STR_OFFSET ) ) {
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
2014-04-17 20:10:16 +08:00
zend_fetch_property_address ( EX_VAR ( opline - > result . var ) , container , property , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( property ) : - 1 ) , BP_VAR_W , ( opline - > extended_value & ZEND_FETCH_MAKE_REF ) ! = 0 TSRMLS_CC ) ;
2014-04-16 01:56:30 +08:00
FREE_OP2 ( ) ;
2014-03-04 21:23:23 +08:00
if ( OP1_TYPE = = IS_VAR & & OP1_FREE & & READY_TO_DESTROY ( free_op1 . var ) ) {
EXTRACT_ZVAL_PTR ( EX_VAR ( opline - > result . 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 ( ) ;
}
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 ;
2014-02-10 14:04:30 +08:00
zval * container ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
property = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2014-03-04 16:27:50 +08:00
container = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
2004-10-23 05:42:14 +08:00
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( container ) = = IS_STR_OFFSET ) ) {
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
}
2014-04-17 20:10:16 +08:00
zend_fetch_property_address ( EX_VAR ( opline - > result . var ) , container , property , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( property ) : - 1 ) , BP_VAR_RW , 0 TSRMLS_CC ) ;
2014-04-16 01:56:30 +08:00
FREE_OP2 ( ) ;
2014-03-04 21:23:23 +08:00
if ( OP1_TYPE = = IS_VAR & & OP1_FREE & & READY_TO_DESTROY ( free_op1 . var ) ) {
EXTRACT_ZVAL_PTR ( EX_VAR ( opline - > result . 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 ( ) ;
}
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 ( ) ;
2014-04-15 15:13:23 +08:00
container = GET_OP1_OBJ_ZVAL_PTR_DEREF ( BP_VAR_IS ) ;
2010-04-20 19:16:39 +08:00
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 ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
2010-04-20 19:16:39 +08:00
} else {
zval * retval ;
/* here we are sure we are dealing with an object */
2014-04-17 20:10:16 +08:00
retval = Z_OBJ_HT_P ( container ) - > read_property ( container , offset , BP_VAR_IS , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( offset ) : - 1 ) , EX_VAR ( opline - > result . var ) TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
2014-02-27 19:40:13 +08:00
if ( retval ! = EX_VAR ( opline - > result . var ) ) {
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , retval ) ;
}
2010-04-20 19:16:39 +08:00
}
2014-04-16 01:56:30 +08:00
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
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
2014-02-10 14:04:30 +08:00
zval * container ;
2004-10-23 05:42:14 +08:00
2013-08-29 17:35:11 +08:00
if ( zend_is_by_ref_func_arg_fetch ( opline , EX ( call ) TSRMLS_CC ) ) {
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 ;
SAVE_OPLINE ( ) ;
property = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2014-03-04 16:27:50 +08:00
container = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2004-10-23 05:42:14 +08:00
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( container ) = = IS_STR_OFFSET ) ) {
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
}
2014-04-17 20:10:16 +08:00
zend_fetch_property_address ( EX_VAR ( opline - > result . var ) , container , property , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( property ) : - 1 ) , BP_VAR_W , 0 TSRMLS_CC ) ;
2014-04-16 01:56:30 +08:00
FREE_OP2 ( ) ;
2014-03-04 21:23:23 +08:00
if ( OP1_TYPE = = IS_VAR & & OP1_FREE & & READY_TO_DESTROY ( free_op1 . var ) ) {
EXTRACT_ZVAL_PTR ( EX_VAR ( opline - > result . 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 ( ) ;
} 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
2014-04-04 23:01:53 +08:00
zend_free_op free_op1 , free_op2 ;
2014-04-22 21:46:34 +08:00
zval * container , * property ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-03-04 16:27:50 +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
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( container ) = = IS_STR_OFFSET ) ) {
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
}
2014-04-17 20:10:16 +08:00
zend_fetch_property_address ( EX_VAR ( opline - > result . var ) , container , property , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( property ) : - 1 ) , BP_VAR_UNSET , 0 TSRMLS_CC ) ;
2014-04-16 01:56:30 +08:00
FREE_OP2 ( ) ;
2014-03-04 21:23:23 +08:00
if ( OP1_TYPE = = IS_VAR & & OP1_FREE & & READY_TO_DESTROY ( free_op1 . var ) ) {
EXTRACT_ZVAL_PTR ( EX_VAR ( opline - > result . 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 ( ) ;
}
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 ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
2004-10-23 05:42:14 +08:00
} else {
zend_free_op free_op2 ;
2014-04-11 19:05:12 +08:00
zval * value = zend_fetch_dimension_address_inner ( Z_ARRVAL_P ( container ) , GET_OP2_ZVAL_PTR_DEREF ( BP_VAR_R ) , OP2_TYPE , BP_VAR_R TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_COPY ( EX_VAR ( 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 ;
2014-02-10 14:04:30 +08:00
zval * object ;
2010-04-20 19:16:39 +08:00
zval * property_name ;
SAVE_OPLINE ( ) ;
2014-03-04 16:27:50 +08:00
object = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2010-04-20 19:16:39 +08:00
property_name = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( object ) = = IS_STR_OFFSET ) ) {
2008-01-24 01:55:55 +08:00
zend_error_noreturn ( E_ERROR , " Cannot use string offset as an array " ) ;
}
2014-04-17 20:10:16 +08:00
zend_assign_to_object ( RETURN_VALUE_USED ( opline ) ? EX_VAR ( opline - > result . var ) : NULL , object , property_name , ( opline + 1 ) - > op1_type , & ( opline + 1 ) - > op1 , execute_data , ZEND_ASSIGN_OBJ , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( property_name ) : - 1 ) TSRMLS_CC ) ;
2014-04-16 01:56:30 +08:00
FREE_OP2 ( ) ;
2014-03-04 16:27:50 +08:00
FREE_OP1_VAR_PTR ( ) ;
2004-10-23 05:42:14 +08:00
/* 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 ;
2014-02-10 14:04:30 +08:00
zval * object_ptr ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-03-04 16:27:50 +08:00
object_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2010-04-20 19:16:39 +08:00
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( object_ptr ) = = IS_STR_OFFSET ) ) {
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
}
2014-03-27 17:39:09 +08:00
if ( UNEXPECTED ( Z_ISREF_P ( object_ptr ) ) & & Z_TYPE_P ( Z_REFVAL_P ( object_ptr ) ) = = IS_OBJECT ) {
2014-03-06 17:11:23 +08:00
object_ptr = Z_REFVAL_P ( object_ptr ) ;
}
2014-02-10 14:04:30 +08:00
if ( Z_TYPE_P ( 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 ) ;
2014-04-17 20:10:16 +08:00
zend_assign_to_object ( RETURN_VALUE_USED ( opline ) ? EX_VAR ( opline - > result . var ) : NULL , object_ptr , property_name , ( opline + 1 ) - > op1_type , & ( opline + 1 ) - > op1 , execute_data , ZEND_ASSIGN_DIM , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( property_name ) : - 1 ) TSRMLS_CC ) ;
2014-04-16 01:56:30 +08:00
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 ;
2014-03-27 22:14:57 +08:00
zval * dim = GET_OP2_ZVAL_PTR_DEREF ( BP_VAR_R ) ;
2014-02-10 14:04:30 +08:00
zval * variable_ptr ;
2004-10-23 05:42:14 +08:00
2014-04-05 05:56:51 +08:00
zend_fetch_dimension_address_W ( EX_VAR ( ( opline + 1 ) - > op2 . var ) , object_ptr , dim , OP2_TYPE 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 ) ;
2014-03-04 16:27:50 +08:00
variable_ptr = _get_zval_ptr_ptr_var ( ( opline + 1 ) - > op2 . var , execute_data , & free_op_data2 TSRMLS_CC ) ;
2014-02-10 14:04:30 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( variable_ptr ) = = IS_STR_OFFSET ) ) {
2014-04-04 06:52:53 +08:00
zend_assign_to_string_offset ( variable_ptr , value , ( opline + 1 ) - > op1_type , ( RETURN_VALUE_USED ( opline ) ? EX_VAR ( opline - > result . var ) : NULL ) TSRMLS_CC ) ;
2014-02-10 14:04:30 +08:00
} else if ( UNEXPECTED ( variable_ptr = = & EG ( error_zval ) ) ) {
2010-04-20 19:16:39 +08:00
if ( IS_TMP_FREE ( free_op_data1 ) ) {
zval_dtor ( value ) ;
}
if ( RETURN_VALUE_USED ( opline ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
2008-03-04 18:06:52 +08:00
}
2014-03-04 16:27:50 +08:00
FREE_OP_VAR_PTR ( free_op_data2 ) ;
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 ) {
2014-02-10 14:04:30 +08:00
value = zend_assign_tmp_to_variable ( variable_ptr , value TSRMLS_CC ) ;
2010-08-11 23:34:06 +08:00
} else if ( ( opline + 1 ) - > op1_type = = IS_CONST ) {
2014-02-10 14:04:30 +08:00
value = zend_assign_const_to_variable ( variable_ptr , value TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
} else {
2014-02-10 14:04:30 +08:00
value = zend_assign_to_variable ( variable_ptr , value TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
}
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , value ) ;
2008-03-04 18:06:52 +08:00
}
2014-03-04 16:27:50 +08:00
FREE_OP_VAR_PTR ( free_op_data2 ) ;
2014-02-28 21:39:08 +08:00
}
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 ;
2014-02-10 14:04:30 +08:00
zval * variable_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 ) ;
2014-04-04 19:22:41 +08:00
variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF ( BP_VAR_W ) ;
2010-04-20 19:16:39 +08:00
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( variable_ptr ) = = IS_STR_OFFSET ) ) {
2014-04-04 06:52:53 +08:00
zend_assign_to_string_offset ( variable_ptr , value , OP2_TYPE , ( RETURN_VALUE_USED ( opline ) ? EX_VAR ( opline - > result . var ) : NULL ) TSRMLS_CC ) ;
2014-02-10 14:04:30 +08:00
} else if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( variable_ptr = = & EG ( error_zval ) ) ) {
2010-04-20 19:16:39 +08:00
if ( IS_OP2_TMP_FREE ( ) ) {
zval_dtor ( value ) ;
}
if ( RETURN_VALUE_USED ( opline ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
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 ) {
2014-02-10 14:04:30 +08:00
value = zend_assign_tmp_to_variable ( variable_ptr , value TSRMLS_CC ) ;
2010-08-11 23:34:06 +08:00
} else if ( OP2_TYPE = = IS_CONST ) {
2014-02-10 14:04:30 +08:00
value = zend_assign_const_to_variable ( variable_ptr , value TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
} else {
2014-02-10 14:04:30 +08:00
value = zend_assign_to_variable ( variable_ptr , value TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
}
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , value ) ;
2008-03-04 18:06:52 +08:00
}
2014-02-28 21:39:08 +08:00
FREE_OP1_VAR_PTR ( ) ;
2007-12-14 22:14:50 +08:00
}
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 ;
2014-02-10 14:04:30 +08:00
zval * variable_ptr ;
zval * value_ptr ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-03-04 16:27:50 +08:00
value_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 & &
2014-03-07 16:25:55 +08:00
opline - > extended_value = = ZEND_RETURNS_FUNCTION & &
2014-04-04 19:22:41 +08:00
! ( Z_VAR_FLAGS_P ( value_ptr ) & IS_VAR_RET_REF ) & &
! Z_ISREF_P ( value_ptr ) ) {
2014-03-04 16:27:50 +08:00
if ( ! OP2_FREE ) {
2014-02-10 14:04:30 +08:00
PZVAL_LOCK ( value_ptr ) ; /* undo the effect of get_zval_ptr_ptr() */
2005-05-06 01:37:25 +08:00
}
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 ) {
2014-03-21 19:33:08 +08:00
if ( ! OP2_FREE ) {
PZVAL_LOCK ( value_ptr ) ;
}
2005-06-23 19:04:35 +08:00
}
2014-04-04 19:22:41 +08:00
variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF ( BP_VAR_W ) ;
2014-03-13 04:30:53 +08:00
if ( OP1_TYPE = = IS_VAR & &
UNEXPECTED ( Z_TYPE_P ( EX_VAR ( opline - > op1 . var ) ) ! = IS_INDIRECT ) & &
2014-04-03 20:53:30 +08:00
UNEXPECTED ( ! Z_ISREF_P ( variable_ptr ) ) ) {
2014-03-04 20:32:40 +08:00
zend_error_noreturn ( E_ERROR , " Cannot assign by reference to overloaded object " ) ;
}
2014-02-10 14:04:30 +08:00
if ( ( OP2_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( value_ptr ) = = IS_STR_OFFSET ) ) | |
( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( variable_ptr ) = = IS_STR_OFFSET ) ) ) {
2008-01-24 01:55:55 +08:00
zend_error_noreturn ( E_ERROR , " Cannot create references to/from string offsets nor overloaded objects " ) ;
}
2014-04-03 20:53:30 +08:00
if ( ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( variable_ptr = = & EG ( error_zval ) ) ) | |
( OP2_TYPE = = IS_VAR & & UNEXPECTED ( value_ptr = = & EG ( error_zval ) ) ) ) {
variable_ptr = & EG ( uninitialized_zval ) ;
} else {
zend_assign_to_variable_reference ( variable_ptr , value_ptr TSRMLS_CC ) ;
}
2004-10-23 05:42:14 +08:00
2008-07-24 19:47:51 +08:00
if ( OP2_TYPE = = IS_VAR & & opline - > extended_value = = ZEND_RETURNS_NEW ) {
2014-03-20 03:51:28 +08:00
if ( ! OP2_FREE ) {
Z_DELREF_P ( variable_ptr ) ;
}
2008-07-24 19:47:51 +08:00
}
2010-04-20 18:57:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , variable_ptr ) ;
2004-10-23 05:42:14 +08:00
}
2014-03-04 16:27:50 +08:00
FREE_OP1_VAR_PTR ( ) ;
2014-02-27 19:40:13 +08:00
FREE_OP2_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 ( ) ;
}
2012-08-22 18:32:03 +08:00
ZEND_VM_HELPER ( zend_leave_helper , ANY , ANY )
2004-10-23 05:42:14 +08:00
{
2014-04-18 17:46:36 +08:00
vm_frame_kind frame_kind = EX ( frame_kind ) ;
2012-12-21 08:56:37 +08:00
2014-04-18 17:46:36 +08:00
if ( frame_kind = = VM_FRAME_NESTED_FUNCTION ) {
i_free_compiled_variables ( execute_data TSRMLS_CC ) ;
if ( UNEXPECTED ( EX ( symbol_table ) ! = NULL ) ) {
zend_clean_and_cache_symbol_table ( EX ( symbol_table ) TSRMLS_CC ) ;
}
2014-06-30 19:43:45 +08:00
if ( UNEXPECTED ( ( EX ( func ) - > op_array . fn_flags & ZEND_ACC_CLOSURE ) ! = 0 ) & & EX ( func ) - > op_array . prototype ) {
zval_ptr_dtor ( ( zval * ) EX ( func ) - > op_array . prototype ) ;
2014-04-18 17:46:36 +08:00
}
2014-07-03 02:01:25 +08:00
EG ( current_execute_data ) = EX ( prev_execute_data ) ;
2014-06-30 19:43:45 +08:00
zend_vm_stack_free_extra_args ( execute_data TSRMLS_CC ) ;
zend_vm_stack_free_call_frame ( execute_data TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
execute_data = EG ( current_execute_data ) ;
2014-03-26 22:07:31 +08:00
2014-04-18 17:46:36 +08:00
if ( Z_OBJ ( EG ( This ) ) ) {
2014-06-30 19:43:45 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) & & ( EX ( opline ) - > op1 . num & ZEND_CALL_CTOR ) ) {
if ( ! ( EX ( opline ) - > op1 . num & ZEND_CALL_CTOR_RESULT_UNUSED ) ) {
2014-04-18 17:46:36 +08:00
Z_DELREF ( EG ( This ) ) ;
}
if ( Z_REFCOUNT ( EG ( This ) ) = = 1 ) {
zend_object_store_ctor_failed ( Z_OBJ ( EG ( This ) ) TSRMLS_CC ) ;
}
2012-08-22 18:32:03 +08:00
}
2014-04-24 19:53:20 +08:00
if ( ! Z_DELREF ( EG ( This ) ) ) {
_zval_dtor_func_for_ptr ( Z_COUNTED ( EG ( This ) ) ZEND_FILE_LINE_CC ) ;
} else if ( UNEXPECTED ( ! Z_GC_INFO ( EG ( This ) ) ) ) {
gc_possible_root ( Z_COUNTED ( EG ( This ) ) TSRMLS_CC ) ;
}
2014-04-18 17:46:36 +08:00
}
2014-04-24 19:53:20 +08:00
Z_OBJ ( EG ( This ) ) = EX ( object ) ;
EG ( scope ) = EX ( scope ) ;
2004-10-23 05:42:14 +08:00
2014-04-18 17:46:36 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
zend_op * opline = EX ( opline ) ;
zend_throw_exception_internal ( NULL TSRMLS_CC ) ;
if ( RETURN_VALUE_USED ( opline ) ) {
zval_ptr_dtor ( EX_VAR ( opline - > result . var ) ) ;
2012-08-22 18:32:03 +08:00
}
2014-04-18 17:46:36 +08:00
HANDLE_EXCEPTION_LEAVE ( ) ;
}
2004-10-23 05:42:14 +08:00
2014-04-22 04:32:29 +08:00
LOAD_OPLINE ( ) ;
2014-04-18 17:46:36 +08:00
ZEND_VM_INC_OPCODE ( ) ;
ZEND_VM_LEAVE ( ) ;
} else if ( frame_kind = = VM_FRAME_NESTED_CODE ) {
zend_detach_symbol_table ( execute_data ) ;
2014-06-30 19:43:45 +08:00
destroy_op_array ( & EX ( func ) - > op_array TSRMLS_CC ) ;
efree ( EX ( func ) ) ;
2014-07-03 02:01:25 +08:00
EG ( current_execute_data ) = EX ( prev_execute_data ) ;
2014-06-30 19:43:45 +08:00
zend_vm_stack_free_call_frame ( execute_data TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2014-04-18 17:46:36 +08:00
execute_data = EG ( current_execute_data ) ;
zend_attach_symbol_table ( execute_data ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
zend_throw_exception_internal ( NULL TSRMLS_CC ) ;
HANDLE_EXCEPTION_LEAVE ( ) ;
}
2010-04-20 19:16:39 +08:00
2014-04-22 04:32:29 +08:00
LOAD_OPLINE ( ) ;
2014-04-18 17:46:36 +08:00
ZEND_VM_INC_OPCODE ( ) ;
ZEND_VM_LEAVE ( ) ;
} else {
if ( frame_kind = = VM_FRAME_TOP_FUNCTION ) {
i_free_compiled_variables ( execute_data TSRMLS_CC ) ;
2014-07-04 22:03:45 +08:00
if ( UNEXPECTED ( EX ( symbol_table ) ! = NULL ) ) {
zend_clean_and_cache_symbol_table ( EX ( symbol_table ) TSRMLS_CC ) ;
}
2014-06-30 19:43:45 +08:00
zend_vm_stack_free_extra_args ( execute_data TSRMLS_CC ) ;
2014-04-18 17:46:36 +08:00
} else /* if (frame_kind == VM_FRAME_TOP_CODE) */ {
zend_array * symbol_table = EX ( symbol_table ) ;
zend_execute_data * old_execute_data ;
zend_detach_symbol_table ( execute_data ) ;
old_execute_data = EX ( prev_execute_data ) ;
while ( old_execute_data ) {
2014-06-30 19:43:45 +08:00
if ( old_execute_data - > func & & ZEND_USER_CODE ( old_execute_data - > func - > op_array . type ) ) {
2014-04-18 17:46:36 +08:00
if ( old_execute_data - > symbol_table = = symbol_table ) {
zend_attach_symbol_table ( old_execute_data ) ;
}
break ;
2012-08-22 18:32:03 +08:00
}
2014-04-18 17:46:36 +08:00
old_execute_data = old_execute_data - > prev_execute_data ;
2012-08-22 18:32:03 +08:00
}
2009-03-18 22:17:15 +08:00
}
2014-06-30 19:43:45 +08:00
if ( ( EX ( func ) - > op_array . fn_flags & ZEND_ACC_CLOSURE ) & & EX ( func ) - > op_array . prototype ) {
zval_ptr_dtor ( ( zval * ) EX ( func ) - > op_array . prototype ) ;
}
2014-07-03 02:01:25 +08:00
EG ( current_execute_data ) = EX ( prev_execute_data ) ;
2014-06-30 19:43:45 +08:00
zend_vm_stack_free_call_frame ( execute_data TSRMLS_CC ) ;
2014-04-18 17:46:36 +08:00
ZEND_VM_RETURN ( ) ;
}
2004-10-23 05:42:14 +08:00
}
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-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 ;
2010-05-24 22:11:39 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-02-18 20:27:38 +08:00
val = GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ;
2011-03-16 13:25:02 +08:00
2014-05-01 05:24:38 +08:00
if ( OP1_TYPE = = IS_TMP_VAR ) {
if ( Z_TYPE_P ( val ) = = IS_TRUE ) {
ZEND_VM_SET_OPCODE ( opline + 1 ) ;
ZEND_VM_CONTINUE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( val ) < = IS_TRUE ) ) {
ZEND_VM_SET_OPCODE ( opline - > op2 . jmp_addr ) ;
ZEND_VM_CONTINUE ( ) ;
2004-10-23 05:42:14 +08:00
}
}
2014-05-01 05:24:38 +08:00
if ( i_zend_is_true ( val TSRMLS_CC ) ) {
opline + + ;
} else {
opline = opline - > op2 . jmp_addr ;
}
FREE_OP1 ( ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
ZEND_VM_JMP ( opline ) ;
2004-10-23 05:42:14 +08:00
}
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 ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-02-18 20:27:38 +08:00
val = GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2014-05-01 05:24:38 +08:00
if ( OP1_TYPE = = IS_TMP_VAR ) {
if ( Z_TYPE_P ( val ) = = IS_TRUE ) {
ZEND_VM_SET_OPCODE ( opline - > op2 . jmp_addr ) ;
ZEND_VM_CONTINUE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( val ) < = IS_TRUE ) ) {
ZEND_VM_SET_OPCODE ( opline + 1 ) ;
ZEND_VM_CONTINUE ( ) ;
2008-07-24 17:42:18 +08:00
}
2007-09-29 03:52:53 +08:00
}
2010-05-24 22:11:39 +08:00
2014-05-01 05:24:38 +08:00
if ( i_zend_is_true ( val TSRMLS_CC ) ) {
opline = opline - > op2 . jmp_addr ;
} else {
opline + + ;
}
FREE_OP1 ( ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
ZEND_VM_JMP ( opline ) ;
2012-08-22 18:32:03 +08:00
}
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 ;
2004-10-23 05:42:14 +08:00
2012-08-22 18:32:03 +08:00
SAVE_OPLINE ( ) ;
2014-02-18 20:27:38 +08:00
val = GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2014-05-01 05:24:38 +08:00
if ( OP1_TYPE = = IS_TMP_VAR ) {
if ( EXPECTED ( Z_TYPE_P ( val ) = = IS_TRUE ) ) {
ZEND_VM_SET_RELATIVE_OPCODE ( opline , opline - > extended_value ) ;
ZEND_VM_CONTINUE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( val ) < = IS_TRUE ) ) {
ZEND_VM_SET_OPCODE ( opline - > op2 . jmp_addr ) ;
ZEND_VM_CONTINUE ( ) ;
2006-08-08 07:24:33 +08:00
}
2004-10-23 05:42:14 +08:00
}
2014-05-01 05:24:38 +08:00
if ( i_zend_is_true ( val TSRMLS_CC ) ) {
opline = ( zend_op * ) ( ( ( char * ) opline ) + opline - > extended_value ) ;
2012-08-22 18:32:03 +08:00
} else {
2014-05-01 05:24:38 +08:00
opline = opline - > op2 . jmp_addr ;
}
FREE_OP1 ( ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
2012-08-22 18:32:03 +08:00
}
2014-05-01 05:24:38 +08:00
ZEND_VM_JMP ( opline ) ;
2012-08-22 18:32:03 +08:00
}
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 ;
SAVE_OPLINE ( ) ;
2014-02-18 20:27:38 +08:00
val = GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ;
2012-08-22 18:32:03 +08:00
2014-05-01 05:24:38 +08:00
if ( OP1_TYPE = = IS_TMP_VAR ) {
if ( Z_TYPE_P ( val ) = = IS_TRUE ) {
ZVAL_TRUE ( EX_VAR ( opline - > result . var ) ) ;
ZEND_VM_SET_OPCODE ( opline + 1 ) ;
ZEND_VM_CONTINUE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( val ) < = IS_TRUE ) ) {
ZVAL_FALSE ( EX_VAR ( opline - > result . var ) ) ;
ZEND_VM_SET_OPCODE ( opline - > op2 . jmp_addr ) ;
ZEND_VM_CONTINUE ( ) ;
2004-10-23 05:42:14 +08:00
}
}
2014-05-01 05:24:38 +08:00
if ( i_zend_is_true ( val TSRMLS_CC ) ) {
ZVAL_TRUE ( EX_VAR ( opline - > result . var ) ) ;
opline + + ;
} else {
ZVAL_FALSE ( EX_VAR ( opline - > result . var ) ) ;
opline = opline - > op2 . jmp_addr ;
2012-08-22 18:32:03 +08:00
}
2014-05-01 05:24:38 +08:00
FREE_OP1 ( ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
ZEND_VM_JMP ( opline ) ;
2004-10-23 05:42:14 +08:00
}
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 ;
2010-04-20 19:16:39 +08:00
2012-08-22 18:32:03 +08:00
SAVE_OPLINE ( ) ;
2014-02-18 20:27:38 +08:00
val = GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2014-05-01 05:24:38 +08:00
if ( OP1_TYPE = = IS_TMP_VAR ) {
if ( Z_TYPE_P ( val ) = = IS_TRUE ) {
ZVAL_TRUE ( EX_VAR ( opline - > result . var ) ) ;
ZEND_VM_SET_OPCODE ( opline - > op2 . jmp_addr ) ;
ZEND_VM_CONTINUE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( val ) < = IS_TRUE ) ) {
ZVAL_FALSE ( EX_VAR ( opline - > result . var ) ) ;
ZEND_VM_SET_OPCODE ( opline + 1 ) ;
ZEND_VM_CONTINUE ( ) ;
}
}
if ( i_zend_is_true ( val TSRMLS_CC ) ) {
ZVAL_TRUE ( EX_VAR ( opline - > result . var ) ) ;
opline = opline - > op2 . jmp_addr ;
2012-08-22 18:32:03 +08:00
} else {
2014-05-01 05:24:38 +08:00
ZVAL_FALSE ( EX_VAR ( opline - > result . var ) ) ;
opline + + ;
2012-08-22 18:32:03 +08:00
}
2014-05-01 05:24:38 +08:00
FREE_OP1 ( ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
2012-08-22 18:32:03 +08:00
}
2014-05-01 05:24:38 +08:00
ZEND_VM_JMP ( opline ) ;
2012-08-22 18:32:03 +08:00
}
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 ) {
2014-02-10 14:04:30 +08:00
zval_dtor ( EX_VAR ( opline - > op1 . var ) ) ;
2012-08-22 18:32:03 +08:00
} else {
2014-02-10 14:04:30 +08:00
zval_ptr_dtor ( EX_VAR ( opline - > op1 . var ) ) ;
2012-08-22 18:32:03 +08:00
}
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
2014-02-10 14:04:30 +08:00
zval * tmp = EX_VAR ( opline - > result . var ) ;
2012-01-26 09:28:37 +08:00
2012-08-22 18:32:03 +08:00
SAVE_OPLINE ( ) ;
2014-02-10 14:04:30 +08:00
ZVAL_EMPTY_STRING ( tmp ) ;
2012-08-22 18:32:03 +08:00
/*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
2014-02-10 14:04:30 +08:00
zval * str = EX_VAR ( opline - > result . 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 */
2014-04-03 19:26:23 +08:00
ZVAL_EMPTY_STRING ( 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
2014-02-10 14:04:30 +08:00
zval * str = EX_VAR ( opline - > result . 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 */
2014-04-03 19:26:23 +08:00
ZVAL_EMPTY_STRING ( 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 ;
2014-02-10 14:04:30 +08:00
zval * str = EX_VAR ( opline - > result . 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 */
2014-04-03 19:26:23 +08:00
ZVAL_EMPTY_STRING ( str ) ;
2012-08-13 23:17:18 +08:00
}
2007-05-18 21:12:05 +08:00
if ( Z_TYPE_P ( var ) ! = IS_STRING ) {
2014-03-27 17:39:09 +08:00
ZVAL_DEREF ( var ) ;
2014-02-19 20:50:09 +08:00
if ( Z_TYPE_P ( var ) ! = IS_STRING ) {
zend_make_printable_zval ( var , & var_copy , & use_copy ) ;
2007-05-18 21:12:05 +08:00
2014-02-19 20:50:09 +08:00
if ( use_copy ) {
var = & var_copy ;
}
2007-05-18 21:12:05 +08:00
}
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 ) {
2014-02-10 14:04:30 +08:00
Z_CE_P ( EX_VAR ( opline - > result . var ) ) = zend_fetch_class ( NULL , 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 ;
2014-04-11 15:15:31 +08:00
zval * class_name = GET_OP2_ZVAL_PTR_DEREF ( BP_VAR_R ) ;
2008-06-11 21:18:41 +08:00
2010-04-20 18:57:45 +08:00
if ( OP2_TYPE = = IS_CONST ) {
2014-04-17 20:10:16 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( class_name ) ) ) {
Z_CE_P ( EX_VAR ( opline - > result . var ) ) = CACHED_PTR ( Z_CACHE_SLOT_P ( class_name ) ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-04-17 19:40:45 +08:00
Z_CE_P ( EX_VAR ( opline - > result . var ) ) = zend_fetch_class_by_name ( Z_STR_P ( class_name ) , opline - > op2 . zv + 1 , opline - > extended_value TSRMLS_CC ) ;
2014-04-17 20:10:16 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( class_name ) , Z_CE_P ( EX_VAR ( opline - > result . var ) ) ) ;
2010-05-24 22:11:39 +08:00
}
2010-04-20 18:57:45 +08:00
} else if ( Z_TYPE_P ( class_name ) = = IS_OBJECT ) {
2014-02-10 14:04:30 +08:00
Z_CE_P ( EX_VAR ( opline - > result . var ) ) = Z_OBJCE_P ( class_name ) ;
2009-04-08 21:19:34 +08:00
} else if ( Z_TYPE_P ( class_name ) = = IS_STRING ) {
2014-02-10 14:04:30 +08:00
Z_CE_P ( EX_VAR ( opline - > result . var ) ) = zend_fetch_class ( Z_STR_P ( class_name ) , opline - > extended_value TSRMLS_CC ) ;
2009-04-08 21:19:34 +08:00
} else {
2013-02-16 22:22:22 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
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 ;
zend_free_op free_op1 , free_op2 ;
2014-02-28 19:58:11 +08:00
zval * object ;
2014-06-30 19:43:45 +08:00
zend_function * fbc ;
zend_class_entry * called_scope ;
zend_object * obj ;
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 ) ) {
2013-02-16 22:22:22 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
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
2014-03-27 17:39:09 +08:00
object = GET_OP1_OBJ_ZVAL_PTR_DEREF ( BP_VAR_R ) ;
2008-06-11 21:18:41 +08:00
2014-06-30 19:43:45 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( object ) ! = IS_OBJECT ) ) {
2013-02-07 23:44:46 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
FREE_OP2 ( ) ;
HANDLE_EXCEPTION ( ) ;
}
2014-06-12 09:07:33 +08:00
zend_error_noreturn ( E_ERROR , " Call to a member function %s() on %s " , Z_STRVAL_P ( function_name ) , zend_get_type_by_const ( Z_TYPE_P ( object ) ) ) ;
2004-10-23 05:42:14 +08:00
}
2008-06-11 21:18:41 +08:00
2014-06-30 19:43:45 +08:00
obj = Z_OBJ_P ( object ) ;
called_scope = zend_get_class_entry ( obj TSRMLS_CC ) ;
if ( OP2_TYPE ! = IS_CONST | |
( fbc = CACHED_POLYMORPHIC_PTR ( Z_CACHE_SLOT_P ( function_name ) , called_scope ) ) = = NULL ) {
zend_object * orig_obj = obj ;
if ( UNEXPECTED ( obj - > handlers - > get_method = = NULL ) ) {
zend_error_noreturn ( E_ERROR , " Object does not support method calls " ) ;
}
/* First, locate the function. */
fbc = obj - > handlers - > get_method ( & obj , Z_STR_P ( function_name ) , ( ( OP2_TYPE = = IS_CONST ) ? ( opline - > op2 . zv + 1 ) : NULL ) TSRMLS_CC ) ;
if ( UNEXPECTED ( fbc = = NULL ) ) {
zend_error_noreturn ( E_ERROR , " Call to undefined method %s::%s() " , Z_OBJ_CLASS_NAME_P ( obj ) , Z_STRVAL_P ( function_name ) ) ;
}
if ( OP2_TYPE = = IS_CONST & &
EXPECTED ( fbc - > type < = ZEND_USER_FUNCTION ) & &
EXPECTED ( ( fbc - > common . fn_flags & ( ZEND_ACC_CALL_VIA_HANDLER | ZEND_ACC_NEVER_CACHE ) ) = = 0 ) & &
EXPECTED ( obj = = orig_obj ) ) {
CACHE_POLYMORPHIC_PTR ( Z_CACHE_SLOT_P ( function_name ) , called_scope , fbc ) ;
}
}
if ( ( fbc - > common . fn_flags & ZEND_ACC_STATIC ) ! = 0 ) {
obj = NULL ;
2011-03-16 13:25:02 +08:00
} else {
2014-06-30 19:43:45 +08:00
GC_REFCOUNT ( obj ) + + ; /* For $this pointer */
2008-06-11 21:18:41 +08:00
}
2013-08-29 17:35:11 +08:00
2014-06-30 19:43:45 +08:00
EX ( call ) = zend_vm_stack_push_call_frame (
fbc , opline - > extended_value , 0 , called_scope , obj , EX ( call ) TSRMLS_CC ) ;
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 ;
2014-06-30 19:43:45 +08:00
zend_object * object ;
zend_function * fbc ;
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 */
2014-04-17 19:40:45 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op1 . zv ) ) ) {
ce = CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op1 . zv ) ) ;
2007-09-29 15:28:34 +08:00
} else {
2014-06-30 19:43:45 +08:00
ce = zend_fetch_class_by_name ( Z_STR_P ( opline - > op1 . zv ) , opline - > op1 . zv + 1 , ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC ) ;
2013-07-14 11:47:06 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
2010-05-24 22:11:39 +08:00
if ( UNEXPECTED ( ce = = NULL ) ) {
2013-07-14 11:47:06 +08:00
zend_error_noreturn ( E_ERROR , " Class '%s' not found " , Z_STRVAL_P ( opline - > op1 . zv ) ) ;
2010-05-24 22:11:39 +08:00
}
2014-04-17 19:40:45 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( opline - > op1 . zv ) , ce ) ;
2007-09-29 15:28:34 +08:00
}
2007-09-29 03:52:53 +08:00
} else {
2014-02-10 14:04:30 +08:00
ce = Z_CE_P ( EX_VAR ( opline - > op1 . var ) ) ;
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 & &
2014-04-17 19:40:45 +08:00
CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ) {
2014-06-30 19:43:45 +08:00
fbc = CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ;
2010-05-24 22:11:39 +08:00
} else if ( OP1_TYPE ! = IS_CONST & &
OP2_TYPE = = IS_CONST & &
2014-06-30 19:43:45 +08:00
( fbc = CACHED_POLYMORPHIC_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) , ce ) ) ) {
2010-05-24 22:11:39 +08:00
/* do nothing */
} else if ( OP2_TYPE ! = IS_UNUSED ) {
2004-10-23 05:42:14 +08:00
zend_free_op free_op2 ;
2007-09-29 15:28:34 +08:00
2014-02-10 14:04:30 +08:00
function_name = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
if ( OP2_TYPE ! = IS_CONST ) {
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( function_name ) ! = IS_STRING ) ) {
2013-02-16 22:22:22 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
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
}
2004-10-23 05:42:14 +08:00
}
2010-04-20 19:16:39 +08:00
2014-02-10 14:04:30 +08:00
if ( ce - > get_static_method ) {
2014-06-30 19:43:45 +08:00
fbc = ce - > get_static_method ( ce , Z_STR_P ( function_name ) TSRMLS_CC ) ;
2014-02-10 14:04:30 +08:00
} else {
2014-06-30 19:43:45 +08:00
fbc = zend_std_get_static_method ( ce , Z_STR_P ( function_name ) , ( ( OP2_TYPE = = IS_CONST ) ? ( opline - > op2 . zv + 1 ) : NULL ) TSRMLS_CC ) ;
2014-02-10 14:04:30 +08:00
}
2014-06-30 19:43:45 +08:00
if ( UNEXPECTED ( fbc = = NULL ) ) {
2014-02-10 14:04:30 +08:00
zend_error_noreturn ( E_ERROR , " Call to undefined method %s::%s() " , ce - > name - > val , Z_STRVAL_P ( function_name ) ) ;
}
if ( OP2_TYPE = = IS_CONST & &
2014-06-30 19:43:45 +08:00
EXPECTED ( fbc - > type < = ZEND_USER_FUNCTION ) & &
EXPECTED ( ( fbc - > common . fn_flags & ( ZEND_ACC_CALL_VIA_HANDLER | ZEND_ACC_NEVER_CACHE ) ) = = 0 ) ) {
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_CONST ) {
2014-06-30 19:43:45 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( function_name ) , fbc ) ;
2008-06-04 02:11:12 +08:00
} else {
2014-06-30 19:43:45 +08:00
CACHE_POLYMORPHIC_PTR ( Z_CACHE_SLOT_P ( function_name ) , ce , 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
}
2014-03-28 06:11:22 +08:00
if ( Z_OBJ ( EG ( This ) ) & & Z_OBJCE ( EG ( This ) ) ! = ce - > constructor - > common . scope & & ( ce - > constructor - > common . fn_flags & ZEND_ACC_PRIVATE ) ) {
2014-02-10 14:04:30 +08:00
zend_error_noreturn ( E_ERROR , " Cannot call private %s::__construct() " , ce - > name - > val ) ;
2006-08-08 07:24:33 +08:00
}
2014-06-30 19:43:45 +08:00
fbc = ce - > constructor ;
2004-10-23 05:42:14 +08:00
}
2014-06-30 19:43:45 +08:00
object = NULL ;
if ( ! ( fbc - > common . fn_flags & ZEND_ACC_STATIC ) ) {
if ( Z_OBJ ( EG ( This ) ) ) {
if ( Z_OBJ_HT ( EG ( This ) ) - > get_class_entry & &
! instanceof_function ( Z_OBJCE ( EG ( This ) ) , ce TSRMLS_CC ) ) {
/* We are calling method of the other (incompatible) class,
but passing $ this . This is done for compatibility with php - 4. */
if ( fbc - > common . fn_flags & ZEND_ACC_ALLOW_STATIC ) {
zend_error ( E_DEPRECATED , " Non-static method %s::%s() should not be called statically, assuming $this from incompatible context " , fbc - > common . scope - > name - > val , fbc - > common . function_name - > val ) ;
} else {
/* 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, assuming $this from incompatible context " , fbc - > common . scope - > name - > val , fbc - > common . function_name - > val ) ;
}
2004-10-23 05:42:14 +08:00
}
2014-06-30 19:43:45 +08:00
object = Z_OBJ ( EG ( This ) ) ;
GC_REFCOUNT ( object ) + + ;
2004-10-23 05:42:14 +08:00
}
2014-06-30 19:43:45 +08:00
}
if ( OP1_TYPE ! = IS_CONST ) {
/* previous opcode is ZEND_FETCH_CLASS */
if ( ( opline - 1 ) - > extended_value = = ZEND_FETCH_CLASS_PARENT | | ( opline - 1 ) - > extended_value = = ZEND_FETCH_CLASS_SELF ) {
2014-07-03 06:34:43 +08:00
ce = EX ( called_scope ) ;
2014-03-28 06:11:22 +08:00
}
2004-10-23 05:42:14 +08:00
}
2013-08-29 17:35:11 +08:00
2014-06-30 19:43:45 +08:00
EX ( call ) = zend_vm_stack_push_call_frame (
fbc , opline - > extended_value , 0 , ce , object , EX ( call ) 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 ( 59 , ZEND_INIT_FCALL_BY_NAME , ANY , CONST | TMP | VAR | CV )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2014-06-30 19:43:45 +08:00
zend_function * fbc ;
zval * function_name , * func ;
2004-10-23 05:42:14 +08:00
if ( OP2_TYPE = = IS_CONST ) {
2014-06-30 19:43:45 +08:00
function_name = ( zval * ) ( opline - > op2 . zv + 1 ) ;
2014-04-17 19:40:45 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ) {
2014-06-30 19:43:45 +08:00
fbc = CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ;
2014-02-10 14:04:30 +08:00
} else if ( UNEXPECTED ( ( func = zend_hash_find ( EG ( function_table ) , Z_STR_P ( function_name ) ) ) = = NULL ) ) {
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 {
2014-06-30 19:43:45 +08:00
fbc = Z_FUNC_P ( func ) ;
CACHE_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) , fbc ) ;
2004-10-23 05:42:14 +08:00
}
2013-08-29 17:35:11 +08:00
2014-06-30 19:43:45 +08:00
EX ( call ) = zend_vm_stack_push_call_frame (
fbc , opline - > extended_value , 0 , NULL , NULL , EX ( call ) TSRMLS_CC ) ;
2013-08-29 17:35:11 +08:00
2010-04-20 19:16:39 +08:00
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE ( ) ;
2004-10-23 05:42:14 +08:00
} else {
2014-02-10 14:04:30 +08:00
zend_string * lcname ;
2010-04-20 19:16:39 +08:00
zend_free_op free_op2 ;
2014-06-30 19:43:45 +08:00
zend_class_entry * called_scope ;
zend_object * object ;
zval * function_name_ptr ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-03-04 16:27:50 +08:00
function_name_ptr = function_name = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2014-03-27 17:39:09 +08:00
ZVAL_DEREF ( function_name ) ;
2010-04-20 19:16:39 +08:00
if ( EXPECTED ( Z_TYPE_P ( function_name ) = = IS_STRING ) ) {
2014-02-10 14:04:30 +08:00
if ( Z_STRVAL_P ( function_name ) [ 0 ] = = ' \\ ' ) {
lcname = STR_ALLOC ( Z_STRLEN_P ( function_name ) - 1 , 0 ) ;
zend_str_tolower_copy ( lcname - > val , Z_STRVAL_P ( function_name ) + 1 , Z_STRLEN_P ( function_name ) - 1 ) ;
2010-04-20 19:16:39 +08:00
} else {
2014-02-10 14:04:30 +08:00
lcname = STR_ALLOC ( Z_STRLEN_P ( function_name ) , 0 ) ;
zend_str_tolower_copy ( lcname - > val , Z_STRVAL_P ( function_name ) , Z_STRLEN_P ( function_name ) ) ;
2012-07-20 06:49:50 +08:00
}
2014-02-10 14:04:30 +08:00
if ( UNEXPECTED ( ( func = zend_hash_find ( EG ( function_table ) , lcname ) ) = = NULL ) ) {
zend_error_noreturn ( E_ERROR , " Call to undefined function %s() " , Z_STRVAL_P ( function_name ) ) ;
2010-04-20 19:16:39 +08:00
}
2014-02-10 14:04:30 +08:00
STR_FREE ( lcname ) ;
2010-04-20 19:16:39 +08:00
FREE_OP2 ( ) ;
2014-06-30 19:43:45 +08:00
fbc = Z_FUNC_P ( func ) ;
called_scope = NULL ;
object = NULL ;
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 ) & &
2014-06-30 19:43:45 +08:00
Z_OBJ_HANDLER_P ( function_name , get_closure ) ( function_name , & called_scope , & fbc , & object TSRMLS_CC ) = = SUCCESS ) {
if ( object ) {
GC_REFCOUNT ( object ) + + ;
2008-07-14 17:49:03 +08:00
}
2013-08-12 14:53:20 +08:00
if ( OP2_TYPE = = IS_VAR & & OP2_FREE & & Z_REFCOUNT_P ( function_name ) = = 1 & &
2014-06-30 19:43:45 +08:00
fbc - > common . fn_flags & ZEND_ACC_CLOSURE ) {
2011-04-20 20:59:18 +08:00
/* Delay closure destruction until its invocation */
2014-06-30 19:43:45 +08:00
fbc - > common . prototype = ( zend_function * ) function_name_ptr ;
2012-08-22 18:32:03 +08:00
} else {
FREE_OP2 ( ) ;
2004-10-23 05:42:14 +08:00
}
2012-08-22 18:32:03 +08:00
} else if ( OP2_TYPE ! = IS_CONST & &
EXPECTED ( Z_TYPE_P ( function_name ) = = IS_ARRAY ) & &
zend_hash_num_elements ( Z_ARRVAL_P ( function_name ) ) = = 2 ) {
2014-02-10 14:04:30 +08:00
zval * obj ;
zval * method ;
2008-04-21 18:14:20 +08:00
2014-02-10 14:04:30 +08:00
obj = zend_hash_index_find ( Z_ARRVAL_P ( function_name ) , 0 ) ;
method = zend_hash_index_find ( Z_ARRVAL_P ( function_name ) , 1 ) ;
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
2014-02-10 14:04:30 +08:00
if ( Z_TYPE_P ( obj ) ! = IS_STRING & & Z_TYPE_P ( obj ) ! = IS_OBJECT ) {
2012-08-22 18:32:03 +08:00
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
2014-02-10 14:04:30 +08:00
if ( Z_TYPE_P ( method ) ! = IS_STRING ) {
2012-08-22 18:32:03 +08:00
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
2014-02-10 14:04:30 +08:00
if ( Z_TYPE_P ( obj ) = = IS_STRING ) {
2014-06-30 19:43:45 +08:00
object = NULL ;
called_scope = zend_fetch_class_by_name ( Z_STR_P ( obj ) , NULL , 0 TSRMLS_CC ) ;
if ( UNEXPECTED ( called_scope = = NULL ) ) {
2012-08-22 18:32:03 +08:00
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
2014-06-30 19:43:45 +08:00
if ( called_scope - > get_static_method ) {
fbc = called_scope - > get_static_method ( called_scope , Z_STR_P ( method ) TSRMLS_CC ) ;
2012-08-22 18:32:03 +08:00
} else {
2014-06-30 19:43:45 +08:00
fbc = zend_std_get_static_method ( called_scope , Z_STR_P ( method ) , NULL TSRMLS_CC ) ;
2014-02-10 14:04:30 +08:00
}
2014-06-30 19:43:45 +08:00
if ( UNEXPECTED ( fbc = = NULL ) ) {
zend_error_noreturn ( E_ERROR , " Call to undefined method %s::%s() " , called_scope - > name - > val , Z_STRVAL_P ( method ) ) ;
2012-08-22 18:32:03 +08:00
}
} else {
2014-06-30 19:43:45 +08:00
called_scope = Z_OBJCE_P ( obj ) ;
object = Z_OBJ_P ( obj ) ;
2007-11-06 22:56:14 +08:00
2014-06-30 19:43:45 +08:00
fbc = Z_OBJ_HT_P ( obj ) - > get_method ( & object , Z_STR_P ( method ) , NULL TSRMLS_CC ) ;
if ( UNEXPECTED ( fbc = = NULL ) ) {
zend_error_noreturn ( E_ERROR , " Call to undefined method %s::%s() " , Z_OBJ_CLASS_NAME_P ( object ) , Z_STRVAL_P ( method ) ) ;
2008-04-21 18:14:20 +08:00
}
2012-08-22 18:32:03 +08:00
2014-06-30 19:43:45 +08:00
if ( ( fbc - > common . fn_flags & ZEND_ACC_STATIC ) ! = 0 ) {
object = NULL ;
2012-08-22 18:32:03 +08:00
} else {
2014-06-30 19:43:45 +08:00
GC_REFCOUNT ( object ) + + ; /* For $this pointer */
2008-04-21 18:14:20 +08:00
}
2005-05-04 16:45:46 +08:00
}
2012-08-22 18:32:03 +08:00
FREE_OP2 ( ) ;
} else {
2013-02-16 22:22:22 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
2012-08-22 18:32:03 +08:00
zend_error_noreturn ( E_ERROR , " Function name must be a string " ) ;
2014-06-30 19:43:45 +08:00
ZEND_VM_CONTINUE ( ) ; /* Never reached */
2004-10-23 05:42:14 +08:00
}
2014-06-30 19:43:45 +08:00
EX ( call ) = zend_vm_stack_push_call_frame (
fbc , opline - > extended_value , 0 , called_scope , object , EX ( call ) TSRMLS_CC ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
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
2014-04-17 19:40:45 +08:00
zval * func_name ;
2014-02-10 14:04:30 +08:00
zval * func ;
2014-06-30 19:43:45 +08:00
zend_function * fbc ;
2012-08-22 18:32:03 +08:00
2014-04-17 19:40:45 +08:00
func_name = opline - > op2 . zv + 1 ;
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ) {
2014-06-30 19:43:45 +08:00
fbc = CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ;
2014-04-17 19:40:45 +08:00
} else if ( ( func = zend_hash_find ( EG ( function_table ) , Z_STR_P ( func_name ) ) ) = = NULL ) {
2012-08-22 18:32:03 +08:00
func_name + + ;
2014-04-17 19:40:45 +08:00
if ( UNEXPECTED ( ( func = zend_hash_find ( EG ( function_table ) , Z_STR_P ( func_name ) ) ) = = NULL ) ) {
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 {
2014-06-30 19:43:45 +08:00
fbc = Z_FUNC_P ( func ) ;
CACHE_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) , fbc ) ;
2004-10-23 05:42:14 +08:00
}
2012-08-22 18:32:03 +08:00
} else {
2014-06-30 19:43:45 +08:00
fbc = Z_FUNC_P ( func ) ;
CACHE_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) , fbc ) ;
2004-10-23 05:42:14 +08:00
}
2014-06-30 19:43:45 +08:00
EX ( call ) = zend_vm_stack_push_call_frame (
fbc , opline - > extended_value , 0 , NULL , NULL , EX ( call ) TSRMLS_CC ) ;
2014-02-10 14:04:30 +08:00
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-06-30 19:43:45 +08:00
ZEND_VM_HANDLER ( 61 , ZEND_INIT_FCALL , ANY , CONST )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2014-06-30 19:43:45 +08:00
zend_free_op free_op2 ;
zval * fname = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2014-02-10 14:04:30 +08:00
zval * func ;
2014-06-30 19:43:45 +08:00
zend_function * fbc ;
2004-10-23 05:42:14 +08:00
2014-04-17 20:10:16 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( fname ) ) ) {
2014-06-30 19:43:45 +08:00
fbc = CACHED_PTR ( Z_CACHE_SLOT_P ( fname ) ) ;
2014-02-10 14:04:30 +08:00
} else if ( UNEXPECTED ( ( func = zend_hash_find ( EG ( function_table ) , Z_STR_P ( fname ) ) ) = = NULL ) ) {
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-02-10 14:04:30 +08:00
zend_error_noreturn ( E_ERROR , " Call to undefined function %s() " , Z_STRVAL_P ( fname ) ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-06-30 19:43:45 +08:00
fbc = Z_FUNC_P ( func ) ;
CACHE_PTR ( Z_CACHE_SLOT_P ( fname ) , fbc ) ;
2004-10-23 05:42:14 +08:00
}
2013-08-29 17:35:11 +08:00
2014-06-30 19:43:45 +08:00
EX ( call ) = zend_vm_stack_push_call_frame (
fbc , opline - > extended_value , 0 , NULL , NULL , EX ( call ) TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2014-06-30 19:43:45 +08:00
FREE_OP2 ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 60 , ZEND_DO_FCALL , ANY , ANY )
{
USE_OPLINE
zend_execute_data * call = EX ( call ) ;
zend_function * fbc = call - > func ;
SAVE_OPLINE ( ) ;
2014-07-07 19:50:44 +08:00
EX ( call ) = call - > prev_nested_call ;
2014-06-30 19:43:45 +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 - > val , fbc - > common . function_name - > val ) ;
}
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 - > val : " " ,
fbc - > common . scope ? " :: " : " " ,
fbc - > common . function_name - > val ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
}
}
if ( fbc - > common . scope & &
! ( fbc - > common . fn_flags & ZEND_ACC_STATIC ) & &
! call - > object ) {
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 - > val , fbc - > common . function_name - > val ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
} 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 - > val , fbc - > common . function_name - > val ) ;
}
}
LOAD_OPLINE ( ) ;
if ( UNEXPECTED ( fbc - > type = = ZEND_INTERNAL_FUNCTION ) ) {
int should_change_scope = 0 ;
zval * ret ;
if ( fbc - > common . scope ) {
should_change_scope = 1 ;
Z_OBJ ( EG ( This ) ) = call - > object ;
/* TODO: we don't set scope if we call an object method ??? */
/* See: ext/pdo_sqlite/tests/pdo_fetch_func_001.phpt */
# if 1
EG ( scope ) = ( call - > object ) ? NULL : fbc - > common . scope ;
# else
EG ( scope ) = fbc - > common . scope ;
# endif
2014-07-03 06:34:43 +08:00
} else {
call - > called_scope = EX ( called_scope ) ;
2014-06-30 19:43:45 +08:00
}
2014-07-04 21:03:44 +08:00
call - > prev_execute_data = execute_data ;
2014-07-03 02:01:25 +08:00
EG ( current_execute_data ) = call ;
2014-06-30 19:43:45 +08:00
if ( fbc - > common . fn_flags & ZEND_ACC_HAS_TYPE_HINTS ) {
zend_uint i ;
zval * p = ZEND_CALL_ARG ( call , 1 ) ;
for ( i = 0 ; i < call - > num_args ; + + i ) {
zend_verify_arg_type ( fbc , i + 1 , p , 0 TSRMLS_CC ) ;
p + + ;
}
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2014-07-03 02:01:25 +08:00
EG ( current_execute_data ) = call - > prev_execute_data ;
zend_vm_stack_free_args ( call TSRMLS_CC ) ;
zend_vm_stack_free_call_frame ( call TSRMLS_CC ) ;
2014-06-30 19:43:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
ZVAL_UNDEF ( EX_VAR ( opline - > result . var ) ) ;
}
if ( UNEXPECTED ( should_change_scope ) ) {
ZEND_VM_C_GOTO ( fcall_end_change_scope ) ;
} else {
ZEND_VM_C_GOTO ( fcall_end ) ;
}
}
}
ret = EX_VAR ( opline - > result . var ) ;
ZVAL_NULL ( ret ) ;
Z_VAR_FLAGS_P ( ret ) = ( fbc - > common . fn_flags & ZEND_ACC_RETURN_REFERENCE ) ! = 0 ? IS_VAR_RET_REF : 0 ;
if ( ! zend_execute_internal ) {
/* saves one function call if zend_execute_internal is not used */
fbc - > internal_function . handler ( call - > num_args , ret TSRMLS_CC ) ;
} else {
2014-07-07 19:50:44 +08:00
zend_execute_internal ( call , ret TSRMLS_CC ) ;
2014-06-30 19:43:45 +08:00
}
2014-07-03 02:01:25 +08:00
EG ( current_execute_data ) = call - > prev_execute_data ;
2014-06-30 19:43:45 +08:00
zend_vm_stack_free_args ( call TSRMLS_CC ) ;
zend_vm_stack_free_call_frame ( call TSRMLS_CC ) ;
if ( ! RETURN_VALUE_USED ( opline ) ) {
zval_ptr_dtor ( ret ) ;
}
2004-10-23 05:42:14 +08:00
2014-06-30 19:43:45 +08:00
if ( UNEXPECTED ( should_change_scope ) ) {
ZEND_VM_C_GOTO ( fcall_end_change_scope ) ;
} else {
ZEND_VM_C_GOTO ( fcall_end ) ;
}
} else if ( EXPECTED ( fbc - > type = = ZEND_USER_FUNCTION ) ) {
zval * return_value = NULL ;
Z_OBJ ( EG ( This ) ) = call - > object ;
EG ( scope ) = fbc - > common . scope ;
2014-07-04 22:03:45 +08:00
call - > symbol_table = NULL ;
2014-06-30 19:43:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
return_value = EX_VAR ( opline - > result . var ) ;
ZVAL_NULL ( return_value ) ;
Z_VAR_FLAGS_P ( return_value ) = ( fbc - > common . fn_flags & ZEND_ACC_RETURN_REFERENCE ) ! = 0 ? IS_VAR_RET_REF : 0 ;
}
if ( UNEXPECTED ( ( fbc - > common . fn_flags & ZEND_ACC_GENERATOR ) ! = 0 ) ) {
if ( RETURN_VALUE_USED ( opline ) ) {
2014-07-07 19:50:44 +08:00
zend_generator_create_zval ( call , & fbc - > op_array , EX_VAR ( opline - > result . var ) TSRMLS_CC ) ;
2014-07-05 21:07:25 +08:00
} else {
zend_vm_stack_free_args ( call TSRMLS_CC ) ;
2014-06-30 19:43:45 +08:00
}
zend_vm_stack_free_call_frame ( call TSRMLS_CC ) ;
} else {
2014-07-04 21:03:44 +08:00
call - > prev_execute_data = execute_data ;
2014-07-04 22:03:45 +08:00
i_init_func_execute_data ( call , & fbc - > op_array , return_value , VM_FRAME_NESTED_FUNCTION TSRMLS_CC ) ;
2014-06-30 19:43:45 +08:00
if ( EXPECTED ( zend_execute_ex = = execute_ex ) ) {
ZEND_VM_ENTER ( ) ;
} else {
execute_ex ( call TSRMLS_CC ) ;
}
}
} else { /* ZEND_OVERLOADED_FUNCTION */
Z_OBJ ( EG ( This ) ) = call - > object ;
//??? EG(scope) = NULL;
EG ( scope ) = fbc - > common . scope ;
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
/* Not sure what should be done here if it's a static method */
if ( EXPECTED ( call - > object ! = NULL ) ) {
2014-07-04 21:03:44 +08:00
call - > prev_execute_data = execute_data ;
2014-07-03 02:01:25 +08:00
EG ( current_execute_data ) = call ;
2014-06-30 19:43:45 +08:00
call - > object - > handlers - > call_method ( fbc - > common . function_name , call - > object , call - > num_args , EX_VAR ( opline - > result . var ) TSRMLS_CC ) ;
2014-07-03 02:01:25 +08:00
EG ( current_execute_data ) = call - > prev_execute_data ;
2014-06-30 19:43:45 +08:00
} else {
zend_error_noreturn ( E_ERROR , " Cannot call overloaded function for non-object " ) ;
}
zend_vm_stack_free_args ( call TSRMLS_CC ) ;
zend_vm_stack_free_call_frame ( call TSRMLS_CC ) ;
if ( fbc - > type = = ZEND_OVERLOADED_FUNCTION_TEMPORARY ) {
STR_RELEASE ( fbc - > common . function_name ) ;
}
efree ( fbc ) ;
if ( ! RETURN_VALUE_USED ( opline ) ) {
zval_ptr_dtor ( EX_VAR ( opline - > result . var ) ) ;
} else {
//??? Z_UNSET_ISREF_P(EX_T(opline->result.var).var.ptr);
//??? Z_SET_REFCOUNT_P(EX_T(opline->result.var).var.ptr, 1);
Z_VAR_FLAGS_P ( EX_VAR ( opline - > result . var ) ) = 0 ;
}
}
ZEND_VM_C_LABEL ( fcall_end_change_scope ) :
if ( Z_OBJ ( EG ( This ) ) ) {
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) & & ( opline - > op1 . num & ZEND_CALL_CTOR ) ) {
if ( ! ( opline - > op1 . num & ZEND_CALL_CTOR_RESULT_UNUSED ) ) {
Z_DELREF ( EG ( This ) ) ;
}
if ( Z_REFCOUNT ( EG ( This ) ) = = 1 ) {
zend_object_store_ctor_failed ( Z_OBJ ( EG ( This ) ) TSRMLS_CC ) ;
}
}
if ( ! Z_DELREF ( EG ( This ) ) ) {
_zval_dtor_func_for_ptr ( Z_COUNTED ( EG ( This ) ) ZEND_FILE_LINE_CC ) ;
} else if ( UNEXPECTED ( ! Z_GC_INFO ( EG ( This ) ) ) ) {
gc_possible_root ( Z_COUNTED ( EG ( This ) ) TSRMLS_CC ) ;
}
}
Z_OBJ ( EG ( This ) ) = EX ( object ) ;
EG ( scope ) = EX ( scope ) ;
ZEND_VM_C_LABEL ( fcall_end ) :
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
zend_throw_exception_internal ( NULL TSRMLS_CC ) ;
if ( RETURN_VALUE_USED ( opline ) ) {
zval_ptr_dtor ( EX_VAR ( opline - > result . var ) ) ;
}
HANDLE_EXCEPTION ( ) ;
}
ZEND_VM_NEXT_OPCODE ( ) ;
2004-10-23 05:42:14 +08:00
}
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 ) ;
2014-02-12 18:29:51 +08:00
if ( ! EX ( return_value ) ) {
2013-05-17 17:15:09 +08:00
FREE_OP1 ( ) ;
2013-03-13 21:51:10 +08:00
} else {
2014-03-04 21:38:19 +08:00
if ( OP1_TYPE = = IS_CONST | | OP1_TYPE = = IS_TMP_VAR ) {
ZVAL_COPY_VALUE ( EX ( return_value ) , retval_ptr ) ;
2014-06-03 07:54:03 +08:00
if ( OP1_TYPE = = IS_CONST ) {
2014-06-05 20:04:11 +08:00
if ( UNEXPECTED ( Z_OPT_COPYABLE_P ( EX ( return_value ) ) ) ) {
zval_copy_ctor_func ( EX ( return_value ) ) ;
}
2013-03-13 21:51:10 +08:00
}
2014-03-04 21:38:19 +08:00
} else if ( Z_ISREF_P ( retval_ptr ) ) {
2014-06-05 20:04:11 +08:00
ZVAL_COPY ( EX ( return_value ) , Z_REFVAL_P ( retval_ptr ) ) ;
2013-05-17 17:15:09 +08:00
FREE_OP1_IF_VAR ( ) ;
2010-04-22 19:56:45 +08:00
} else {
2014-02-12 18:29:51 +08:00
ZVAL_COPY_VALUE ( EX ( return_value ) , retval_ptr ) ;
2013-05-17 17:15:09 +08:00
if ( OP1_TYPE = = IS_CV ) {
2014-04-04 06:52:53 +08:00
if ( Z_OPT_REFCOUNTED_P ( retval_ptr ) ) Z_ADDREF_P ( retval_ptr ) ;
2013-05-17 17:15:09 +08:00
}
2010-04-22 19:56:45 +08:00
}
}
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 ;
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 {
2013-11-28 00:30:35 +08:00
if ( OP1_TYPE = = IS_CONST | | OP1_TYPE = = IS_TMP_VAR | |
( OP1_TYPE = = IS_VAR & & opline - > extended_value = = ZEND_RETURNS_VALUE ) ) {
2004-10-23 05:42:14 +08:00
/* 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 ) ;
2014-02-12 18:29:51 +08:00
if ( ! EX ( return_value ) ) {
2010-04-22 19:56:45 +08:00
if ( OP1_TYPE = = IS_TMP_VAR ) {
FREE_OP1 ( ) ;
}
} else {
2014-02-12 18:29:51 +08:00
ZVAL_COPY_VALUE ( EX ( return_value ) , retval_ptr ) ;
2014-06-03 07:54:03 +08:00
if ( OP1_TYPE ! = IS_TMP_VAR ) {
zval_opt_copy_ctor_no_imm ( EX ( return_value ) ) ;
2014-06-03 06:43:53 +08:00
}
2010-04-22 19:56:45 +08:00
}
break ;
2004-10-23 05:42:14 +08:00
}
2014-03-04 16:27:50 +08:00
retval_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2004-10-23 05:42:14 +08:00
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( retval_ptr ) = = IS_STR_OFFSET ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Cannot return string offsets by reference " ) ;
}
2014-02-12 18:29:51 +08:00
if ( OP1_TYPE = = IS_VAR & & ! Z_ISREF_P ( retval_ptr ) ) {
2014-03-07 16:25:55 +08:00
if ( opline - > extended_value = = ZEND_RETURNS_FUNCTION & &
2014-04-03 19:26:23 +08:00
( Z_VAR_FLAGS_P ( retval_ptr ) & IS_VAR_RET_REF ) ) {
2014-03-07 16:25:55 +08:00
} else {
2014-03-04 16:27:50 +08:00
zend_error ( E_NOTICE , " Only variable references should be returned by reference " ) ;
if ( EX ( return_value ) ) {
zval tmp ;
ZVAL_DUP ( & tmp , retval_ptr ) ;
ZVAL_NEW_REF ( EX ( return_value ) , & tmp ) ;
}
break ;
2014-03-07 16:25:55 +08:00
}
2004-10-23 05:42:14 +08:00
}
2014-02-12 18:29:51 +08:00
if ( EX ( return_value ) ) {
2014-06-05 20:04:11 +08:00
ZVAL_MAKE_REF ( retval_ptr ) ;
Z_ADDREF_P ( retval_ptr ) ;
ZVAL_REF ( EX ( return_value ) , Z_REF_P ( retval_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
2013-05-17 17:15:09 +08:00
FREE_OP1_VAR_PTR ( ) ;
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
{
2014-02-26 17:58:59 +08:00
/* The generator object is stored in EX(return_value) */
zend_generator * generator = ( zend_generator * ) EX ( return_value ) ;
2012-12-11 21:25:32 +08:00
/* Close the generator to free up resources */
2014-02-12 18:29:51 +08:00
zend_generator_close ( generator , 1 TSRMLS_CC ) ;
2012-12-11 21:25:32 +08:00
/* 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 ;
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-05-07 02:01:19 +08:00
value = GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_CONST | | UNEXPECTED ( Z_TYPE_P ( value ) ! = IS_OBJECT ) ) {
2013-02-16 22:22:22 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Can only throw objects " ) ;
}
2013-02-16 22:22:22 +08:00
2008-08-14 18:24:52 +08:00
zend_exception_save ( TSRMLS_C ) ;
2014-05-07 02:02:26 +08:00
if ( OP1_TYPE ! = IS_TMP_VAR ) {
2014-04-21 17:19:52 +08:00
if ( Z_REFCOUNTED_P ( value ) ) Z_ADDREF_P ( value ) ;
2004-10-23 05:42:14 +08:00
}
2014-04-21 17:19:52 +08:00
zend_throw_exception_object ( value 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 ;
2014-02-10 14:04:30 +08:00
zend_object * 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 ) {
2014-06-30 19:43:45 +08:00
ZEND_VM_SET_OPCODE ( & EX ( func ) - > op_array . opcodes [ opline - > extended_value ] ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_CONTINUE ( ) ; /* CHECK_ME */
}
2014-04-17 19:40:45 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op1 . zv ) ) ) {
catch_ce = CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op1 . zv ) ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-04-17 19:40:45 +08:00
catch_ce = zend_fetch_class_by_name ( Z_STR_P ( opline - > op1 . zv ) , opline - > op1 . zv + 1 , ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC ) ;
2012-05-13 13:12:48 +08:00
2014-04-17 19:40:45 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( opline - > op1 . zv ) , catch_ce ) ;
2010-05-24 22:11:39 +08:00
}
2014-04-16 01:56:30 +08:00
ce = zend_get_class_entry ( EG ( exception ) TSRMLS_CC ) ;
2010-04-24 21:32:30 +08:00
# ifdef HAVE_DTRACE
if ( DTRACE_EXCEPTION_CAUGHT_ENABLED ( ) ) {
2013-08-14 11:42:39 +08:00
DTRACE_EXCEPTION_CAUGHT ( ( char * ) ce - > name ) ;
2010-04-24 21:32:30 +08:00
}
# 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
}
2014-06-30 19:43:45 +08:00
ZEND_VM_SET_OPCODE ( & EX ( func ) - > op_array . opcodes [ opline - > extended_value ] ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_CONTINUE ( ) ; /* CHECK_ME */
}
}
2010-05-24 22:46:31 +08:00
exception = EG ( exception ) ;
2014-03-27 20:00:25 +08:00
if ( Z_REFCOUNTED_P ( EX_VAR ( opline - > op2 . var ) ) ) {
zval_ptr_dtor ( EX_VAR ( opline - > op2 . var ) ) ;
2014-02-10 14:04:30 +08:00
}
2014-03-27 20:00:25 +08:00
ZVAL_OBJ ( EX_VAR ( opline - > op2 . var ) , EG ( exception ) ) ;
2010-05-24 22:46:31 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = exception ) ) {
2014-04-02 18:34:44 +08:00
GC_REFCOUNT ( 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
2014-06-30 19:43:45 +08:00
zval * value , * arg ;
2014-04-22 16:33:00 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-06-30 19:43:45 +08:00
if ( opline - > extended_value ! = ZEND_ARG_COMPILE_TIME_BOUND ) {
if ( ARG_MUST_BE_SENT_BY_REF ( EX ( call ) - > func , opline - > op2 . num ) ) {
2014-02-26 23:25:10 +08:00
zend_error_noreturn ( E_ERROR , " Cannot pass parameter %d by reference " , opline - > op2 . num ) ;
2013-08-29 17:35:11 +08:00
}
2004-10-23 05:42:14 +08:00
}
2013-08-29 17:35:11 +08:00
2014-04-22 16:33:00 +08:00
value = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-06-30 19:43:45 +08:00
arg = ZEND_CALL_ARG ( EX ( call ) , opline - > op2 . num ) ;
EX ( call ) - > num_args = opline - > op2 . num ;
ZVAL_COPY_VALUE ( arg , value ) ;
2014-04-22 16:33:00 +08:00
if ( OP1_TYPE = = IS_CONST ) {
2014-06-30 19:43:45 +08:00
if ( UNEXPECTED ( Z_OPT_COPYABLE_P ( arg ) ) ) {
zval_copy_ctor_func ( arg ) ;
2014-06-05 20:04:11 +08:00
}
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
2014-06-30 19:43:45 +08:00
zval * varptr , * arg ;
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2014-02-10 14:04:30 +08:00
varptr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-06-30 19:43:45 +08:00
arg = ZEND_CALL_ARG ( EX ( call ) , opline - > op2 . num ) ;
EX ( call ) - > num_args = opline - > op2 . num ;
2014-02-10 14:04:30 +08:00
if ( Z_ISREF_P ( varptr ) ) {
2014-06-30 19:43:45 +08:00
ZVAL_COPY ( arg , Z_REFVAL_P ( varptr ) ) ;
2014-04-16 05:45:40 +08:00
FREE_OP1 ( ) ;
2014-04-05 06:14:17 +08:00
} else {
2014-06-30 19:43:45 +08:00
ZVAL_COPY_VALUE ( arg , varptr ) ;
2014-04-05 06:14:17 +08:00
if ( OP1_TYPE = = IS_CV ) {
2014-06-30 19:43:45 +08:00
if ( Z_OPT_REFCOUNTED_P ( arg ) ) Z_ADDREF_P ( arg ) ;
2014-04-05 06:14:17 +08:00
}
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 ;
2014-06-30 19:43:45 +08:00
zval * varptr , * arg ;
2005-09-20 00:02:21 +08:00
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 ) ;
}
2013-08-29 17:35:11 +08:00
} else {
2014-06-30 19:43:45 +08:00
if ( ! ARG_SHOULD_BE_SENT_BY_REF ( EX ( call ) - > func , opline - > op2 . num ) ) {
2013-08-29 17:35:11 +08:00
ZEND_VM_DISPATCH_TO_HELPER ( zend_send_by_var_helper ) ;
}
2004-10-23 05:42:14 +08:00
}
2006-05-12 05:07:39 +08:00
2013-05-17 17:15:09 +08:00
varptr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-03-05 03:54:05 +08:00
if ( ( ! ( opline - > extended_value & ZEND_ARG_SEND_FUNCTION ) | |
2014-04-03 19:26:23 +08:00
( Z_VAR_FLAGS_P ( varptr ) & IS_VAR_RET_REF ) ) & &
2014-03-07 20:45:32 +08:00
( ( ! Z_REFCOUNTED_P ( varptr ) & & Z_TYPE_P ( varptr ) ! = IS_STRING ) | |
2014-03-07 16:25:55 +08:00
Z_ISREF_P ( varptr ) | |
2014-03-07 20:45:32 +08:00
Z_TYPE_P ( varptr ) = = IS_OBJECT | |
( Z_REFCOUNTED_P ( varptr ) & & Z_REFCOUNT_P ( varptr ) = = 1 ) ) ) {
2014-03-07 16:25:55 +08:00
2014-06-05 20:04:11 +08:00
ZVAL_MAKE_REF ( varptr ) ;
2014-04-22 16:33:00 +08:00
if ( OP1_TYPE = = IS_CV ) {
Z_ADDREF_P ( varptr ) ;
2014-03-05 03:54:05 +08:00
}
2014-06-30 19:43:45 +08:00
arg = ZEND_CALL_ARG ( EX ( call ) , opline - > op2 . num ) ;
EX ( call ) - > num_args = opline - > op2 . num ;
ZVAL_COPY_VALUE ( arg , varptr ) ;
2014-03-05 03:54:05 +08:00
} else {
2009-07-28 20:35:27 +08:00
if ( ( opline - > extended_value & ZEND_ARG_COMPILE_TIME_BOUND ) ?
! ( opline - > extended_value & ZEND_ARG_SEND_SILENT ) :
2014-06-30 19:43:45 +08:00
! ARG_MAY_BE_SENT_BY_REF ( EX ( call ) - > func , opline - > op2 . num ) ) {
2009-01-20 21:21:52 +08:00
zend_error ( E_STRICT , " Only variables should be passed by reference " ) ;
}
2014-06-30 19:43:45 +08:00
arg = ZEND_CALL_ARG ( EX ( call ) , opline - > op2 . num ) ;
EX ( call ) - > num_args = opline - > op2 . num ;
ZVAL_COPY ( arg , varptr ) ;
2013-05-17 17:15:09 +08:00
FREE_OP1_IF_VAR ( ) ;
2014-03-05 03:54:05 +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 ( 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 ;
2014-06-30 19:43:45 +08:00
zval * varptr , * arg ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-03-04 16:27:50 +08:00
varptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2004-10-23 05:42:14 +08:00
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( varptr ) = = IS_STR_OFFSET ) ) {
2004-10-23 05:42:14 +08:00
zend_error_noreturn ( E_ERROR , " Only variables can be passed by reference " ) ;
}
2014-06-30 19:43:45 +08:00
arg = ZEND_CALL_ARG ( EX ( call ) , opline - > op2 . num ) ;
EX ( call ) - > num_args = opline - > op2 . num ;
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( varptr = = & EG ( error_zval ) ) ) {
2014-06-30 19:43:45 +08:00
ZVAL_NEW_REF ( arg , & EG ( uninitialized_zval ) ) ;
2011-03-16 19:14:33 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
2010-07-05 17:08:35 +08:00
}
2014-03-13 04:30:53 +08:00
if ( Z_ISREF_P ( varptr ) ) {
2014-03-11 18:49:25 +08:00
Z_ADDREF_P ( varptr ) ;
2014-06-30 19:43:45 +08:00
ZVAL_COPY_VALUE ( arg , varptr ) ;
2014-04-11 16:43:22 +08:00
} else if ( OP1_TYPE = = IS_VAR & &
2014-04-22 17:10:53 +08:00
UNEXPECTED ( Z_TYPE_P ( EX_VAR ( opline - > op1 . var ) ) ! = IS_INDIRECT ) ) {
2014-06-30 19:43:45 +08:00
ZVAL_COPY_VALUE ( arg , varptr ) ;
ZVAL_MAKE_REF ( arg ) ;
2014-03-13 04:30:53 +08:00
} else {
2014-06-05 20:04:11 +08:00
ZVAL_MAKE_REF ( varptr ) ;
2014-04-11 16:43:22 +08:00
Z_ADDREF_P ( varptr ) ;
2014-06-30 19:43:45 +08:00
ZVAL_REF ( arg , Z_REF_P ( varptr ) ) ;
2014-03-11 18:49:25 +08:00
}
2014-04-11 16:43:22 +08:00
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 66 , ZEND_SEND_VAR , VAR | CV , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2014-06-30 19:43:45 +08:00
zval * varptr , * arg ;
2014-04-22 16:33:00 +08:00
zend_free_op free_op1 ;
2004-10-23 05:42:14 +08:00
2014-06-30 19:43:45 +08:00
if ( opline - > extended_value ! = ZEND_ARG_COMPILE_TIME_BOUND ) {
if ( ARG_SHOULD_BE_SENT_BY_REF ( EX ( call ) - > func , opline - > op2 . num ) ) {
2013-08-29 17:35:11 +08:00
ZEND_VM_DISPATCH_TO_HANDLER ( ZEND_SEND_REF ) ;
}
2004-10-23 05:42:14 +08:00
}
2014-04-22 16:33:00 +08:00
varptr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-06-30 19:43:45 +08:00
arg = ZEND_CALL_ARG ( EX ( call ) , opline - > op2 . num ) ;
EX ( call ) - > num_args = opline - > op2 . num ;
2014-04-22 16:33:00 +08:00
if ( Z_ISREF_P ( varptr ) ) {
2014-06-30 19:43:45 +08:00
ZVAL_COPY ( arg , Z_REFVAL_P ( varptr ) ) ;
2014-04-22 16:33:00 +08:00
FREE_OP1 ( ) ;
} else {
2014-06-30 19:43:45 +08:00
ZVAL_COPY_VALUE ( arg , varptr ) ;
2014-04-22 16:33:00 +08:00
if ( OP1_TYPE = = IS_CV ) {
2014-06-30 19:43:45 +08:00
if ( Z_OPT_REFCOUNTED_P ( arg ) ) Z_ADDREF_P ( arg ) ;
2014-04-22 16:33:00 +08:00
}
}
ZEND_VM_NEXT_OPCODE ( ) ;
2004-10-23 05:42:14 +08:00
}
2013-08-29 17:35:11 +08:00
ZEND_VM_HANDLER ( 165 , ZEND_SEND_UNPACK , ANY , ANY )
{
USE_OPLINE
zend_free_op free_op1 ;
zval * args ;
int arg_num ;
SAVE_OPLINE ( ) ;
args = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-06-30 19:43:45 +08:00
arg_num = EX ( call ) - > num_args + 1 ;
2013-08-29 17:35:11 +08:00
2014-03-26 22:07:31 +08:00
ZEND_VM_C_LABEL ( send_again ) :
2013-08-29 17:35:11 +08:00
switch ( Z_TYPE_P ( args ) ) {
case IS_ARRAY : {
HashTable * ht = Z_ARRVAL_P ( args ) ;
2014-04-26 16:40:12 +08:00
zval * arg , * top ;
2014-04-19 04:08:14 +08:00
zend_string * name ;
2013-08-29 17:35:11 +08:00
2014-07-05 20:12:20 +08:00
zend_vm_stack_extend_call_frame ( & EX ( call ) , arg_num - 1 , zend_hash_num_elements ( ht ) TSRMLS_CC ) ;
2013-08-29 17:35:11 +08:00
2014-05-29 22:21:56 +08:00
if ( OP1_TYPE ! = IS_CONST & & OP1_TYPE ! = IS_TMP_VAR & & Z_IMMUTABLE_P ( args ) ) {
int i ;
int separate = 0 ;
/* check if any of arguments are going to be passed by reference */
for ( i = 0 ; i < zend_hash_num_elements ( ht ) ; i + + ) {
2014-06-30 19:43:45 +08:00
if ( ARG_SHOULD_BE_SENT_BY_REF ( EX ( call ) - > func , arg_num + i ) ) {
2014-05-29 22:21:56 +08:00
separate = 1 ;
break ;
}
}
if ( separate ) {
zval_copy_ctor ( args ) ;
ht = Z_ARRVAL_P ( args ) ;
}
}
2014-04-22 21:46:34 +08:00
ZEND_HASH_FOREACH_STR_KEY_VAL ( ht , name , arg ) {
2014-04-19 04:08:14 +08:00
if ( name ) {
2013-08-29 17:35:11 +08:00
zend_error ( E_RECOVERABLE_ERROR , " Cannot unpack array with string keys " ) ;
FREE_OP1 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-06-30 19:43:45 +08:00
top = ZEND_CALL_ARG ( EX ( call ) , arg_num ) ;
if ( ARG_SHOULD_BE_SENT_BY_REF ( EX ( call ) - > func , arg_num ) ) {
2014-05-29 22:21:56 +08:00
if ( ! Z_IMMUTABLE_P ( args ) ) {
2014-06-05 20:04:11 +08:00
ZVAL_MAKE_REF ( arg ) ;
2014-05-29 22:21:56 +08:00
Z_ADDREF_P ( arg ) ;
2014-06-05 20:04:11 +08:00
ZVAL_REF ( top , Z_REF_P ( arg ) ) ;
2014-05-29 22:21:56 +08:00
} else {
ZVAL_DUP ( top , arg ) ;
}
2014-02-10 14:04:30 +08:00
} else if ( Z_ISREF_P ( arg ) ) {
2014-06-30 19:43:45 +08:00
//TODO: change into ZVAL_COPY()???
2014-04-26 16:40:12 +08:00
ZVAL_DUP ( top , Z_REFVAL_P ( arg ) ) ;
2013-08-29 17:35:11 +08:00
} else {
2014-04-26 16:40:12 +08:00
ZVAL_COPY ( top , arg ) ;
2013-08-29 17:35:11 +08:00
}
2014-06-30 19:43:45 +08:00
EX ( call ) - > num_args + + ;
2014-04-19 04:08:14 +08:00
arg_num + + ;
} ZEND_HASH_FOREACH_END ( ) ;
2013-08-29 17:35:11 +08:00
break ;
}
case IS_OBJECT : {
zend_class_entry * ce = Z_OBJCE_P ( args ) ;
zend_object_iterator * iter ;
if ( ! ce | | ! ce - > get_iterator ) {
zend_error ( E_WARNING , " Only arrays and Traversables can be unpacked " ) ;
break ;
}
iter = ce - > get_iterator ( ce , args , 0 TSRMLS_CC ) ;
if ( UNEXPECTED ( ! iter ) ) {
FREE_OP1 ( ) ;
if ( ! EG ( exception ) ) {
zend_throw_exception_ex (
2014-02-26 20:17:28 +08:00
NULL , 0 TSRMLS_CC , " Object of type %s did not create an Iterator " , ce - > name - > val
2013-08-29 17:35:11 +08:00
) ;
}
HANDLE_EXCEPTION ( ) ;
}
if ( iter - > funcs - > rewind ) {
iter - > funcs - > rewind ( iter TSRMLS_CC ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
ZEND_VM_C_GOTO ( unpack_iter_dtor ) ;
}
}
for ( ; iter - > funcs - > valid ( iter TSRMLS_CC ) = = SUCCESS ; + + arg_num ) {
2014-06-30 19:43:45 +08:00
zval * arg , * top ;
2013-08-29 17:35:11 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
ZEND_VM_C_GOTO ( unpack_iter_dtor ) ;
}
2014-02-26 20:17:28 +08:00
arg = iter - > funcs - > get_current_data ( iter TSRMLS_CC ) ;
2013-08-29 17:35:11 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
ZEND_VM_C_GOTO ( unpack_iter_dtor ) ;
}
if ( iter - > funcs - > get_current_key ) {
zval key ;
iter - > funcs - > get_current_key ( iter , & key TSRMLS_CC ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
ZEND_VM_C_GOTO ( unpack_iter_dtor ) ;
}
if ( Z_TYPE ( key ) = = IS_STRING ) {
zend_error ( E_RECOVERABLE_ERROR ,
" Cannot unpack Traversable with string keys " ) ;
zval_dtor ( & key ) ;
ZEND_VM_C_GOTO ( unpack_iter_dtor ) ;
}
zval_dtor ( & key ) ;
}
2014-06-30 19:43:45 +08:00
if ( ARG_MUST_BE_SENT_BY_REF ( EX ( call ) - > func , arg_num ) ) {
2013-08-29 17:35:11 +08:00
zend_error (
E_WARNING , " Cannot pass by-reference argument %d of %s%s%s() "
" by unpacking a Traversable, passing by-value instead " , arg_num ,
2014-06-30 19:43:45 +08:00
EX ( call ) - > func - > common . scope ? EX ( call ) - > func - > common . scope - > name - > val : " " ,
EX ( call ) - > func - > common . scope ? " :: " : " " ,
EX ( call ) - > func - > common . function_name - > val
2013-08-29 17:35:11 +08:00
) ;
}
2014-02-26 20:17:28 +08:00
if ( Z_ISREF_P ( arg ) ) {
ZVAL_DUP ( arg , Z_REFVAL_P ( arg ) ) ;
2013-08-29 17:35:11 +08:00
} else {
2014-02-26 20:17:28 +08:00
if ( Z_REFCOUNTED_P ( arg ) ) Z_ADDREF_P ( arg ) ;
2013-08-29 17:35:11 +08:00
}
2014-07-05 20:12:20 +08:00
zend_vm_stack_extend_call_frame ( & EX ( call ) , arg_num - 1 , 1 TSRMLS_CC ) ;
2014-06-30 19:43:45 +08:00
top = ZEND_CALL_ARG ( EX ( call ) , arg_num ) ;
ZVAL_COPY_VALUE ( top , arg ) ;
EX ( call ) - > num_args + + ;
2013-08-29 17:35:11 +08:00
iter - > funcs - > move_forward ( iter TSRMLS_CC ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
ZEND_VM_C_GOTO ( unpack_iter_dtor ) ;
}
}
ZEND_VM_C_LABEL ( unpack_iter_dtor ) :
2014-03-21 03:28:24 +08:00
zend_iterator_dtor ( iter TSRMLS_CC ) ;
2013-08-29 17:35:11 +08:00
break ;
}
2014-03-06 18:23:16 +08:00
case IS_REFERENCE :
args = Z_REFVAL_P ( args ) ;
2014-03-26 22:07:31 +08:00
ZEND_VM_C_GOTO ( send_again ) ;
2014-03-06 18:23:16 +08:00
break ;
2013-08-29 17:35:11 +08:00
default :
zend_error ( E_WARNING , " Only arrays and Traversables can be unpacked " ) ;
}
FREE_OP1 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
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 ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-06-30 19:43:45 +08:00
if ( UNEXPECTED ( arg_num > EX ( num_args ) ) ) {
2014-04-04 18:36:34 +08:00
zend_verify_missing_arg ( execute_data , arg_num TSRMLS_CC ) ;
2014-06-30 19:43:45 +08:00
CHECK_EXCEPTION ( ) ;
} else if ( UNEXPECTED ( ( EX ( func ) - > op_array . fn_flags & ZEND_ACC_HAS_TYPE_HINTS ) ! = 0 ) ) {
zval * param = _get_zval_ptr_cv_undef_BP_VAR_W ( execute_data , opline - > result . var TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2014-06-30 19:43:45 +08:00
zend_verify_arg_type ( EX ( func ) , arg_num , param , opline - > extended_value TSRMLS_CC ) ;
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
2010-04-20 18:57:45 +08:00
zend_uint arg_num = opline - > op1 . num ;
2014-06-30 19:43:45 +08:00
zval * param ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-06-30 19:43:45 +08:00
param = _get_zval_ptr_cv_undef_BP_VAR_W ( execute_data , opline - > result . var TSRMLS_CC ) ;
if ( arg_num > EX ( num_args ) ) {
ZVAL_COPY_VALUE ( param , opline - > op2 . zv ) ;
if ( Z_OPT_CONSTANT_P ( param ) ) {
zval_update_constant ( param , 0 TSRMLS_CC ) ;
2014-03-06 04:15:56 +08:00
} else {
2014-04-04 07:55:27 +08:00
/* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
2014-06-30 19:43:45 +08:00
if ( UNEXPECTED ( Z_OPT_COPYABLE_P ( param ) ) ) {
zval_copy_ctor_func ( param ) ;
2014-04-04 07:55:27 +08:00
}
2014-03-06 04:15:56 +08:00
}
2004-10-23 05:42:14 +08:00
}
2014-06-30 19:43:45 +08:00
if ( UNEXPECTED ( ( EX ( func ) - > op_array . fn_flags & ZEND_ACC_HAS_TYPE_HINTS ) ! = 0 ) ) {
zend_verify_arg_type ( EX ( func ) , arg_num , param , opline - > extended_value TSRMLS_CC ) ;
2014-04-04 18:36:34 +08:00
}
2008-04-24 23:45:46 +08:00
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2013-09-27 00:39:17 +08:00
ZEND_VM_HANDLER ( 164 , ZEND_RECV_VARIADIC , ANY , ANY )
{
USE_OPLINE
zend_uint arg_num = opline - > op1 . num ;
2014-06-30 19:43:45 +08:00
zend_uint arg_count = EX ( num_args ) ;
2014-02-10 14:04:30 +08:00
zval * params ;
2013-09-27 00:39:17 +08:00
SAVE_OPLINE ( ) ;
2014-04-04 18:36:34 +08:00
params = _get_zval_ptr_cv_undef_BP_VAR_W ( execute_data , opline - > result . var TSRMLS_CC ) ;
2013-09-27 00:39:17 +08:00
if ( arg_num < = arg_count ) {
2014-06-30 19:43:45 +08:00
zval * param ;
2013-09-27 00:39:17 +08:00
array_init_size ( params , arg_count - arg_num + 1 ) ;
2014-06-30 19:43:45 +08:00
param = EX_VAR_NUM ( EX ( func ) - > op_array . last_var + EX ( func ) - > op_array . T ) ;
if ( UNEXPECTED ( ( EX ( func ) - > op_array . fn_flags & ZEND_ACC_HAS_TYPE_HINTS ) ! = 0 ) ) {
do {
zend_verify_arg_type ( EX ( func ) , arg_num , param , opline - > extended_value TSRMLS_CC ) ;
2014-05-26 21:16:16 +08:00
zend_hash_next_index_insert_new ( Z_ARRVAL_P ( params ) , param ) ;
2014-04-04 18:36:34 +08:00
if ( Z_REFCOUNTED_P ( param ) ) Z_ADDREF_P ( param ) ;
param + + ;
} while ( + + arg_num < = arg_count ) ;
} else {
do {
2014-05-26 21:16:16 +08:00
zend_hash_next_index_insert_new ( Z_ARRVAL_P ( params ) , param ) ;
2014-04-04 18:36:34 +08:00
if ( Z_REFCOUNTED_P ( param ) ) Z_ADDREF_P ( param ) ;
param + + ;
} while ( + + arg_num < = arg_count ) ;
}
2013-09-27 00:39:17 +08:00
} else {
array_init ( params ) ;
}
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
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 ;
2014-02-10 14:04:30 +08:00
zval * retval = EX_VAR ( opline - > result . 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 */
2013-12-18 14:25:05 +08:00
ZVAL_BOOL ( retval , i_zend_is_true ( GET_OP1_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ) ;
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 ,
2014-06-30 19:43:45 +08:00
& EX ( func ) - > op_array , execute_data TSRMLS_CC ) ;
ZEND_VM_JMP ( EX ( func ) - > 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 ,
2014-06-30 19:43:45 +08:00
& EX ( func ) - > op_array , execute_data TSRMLS_CC ) ;
ZEND_VM_JMP ( EX ( func ) - > 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 ,
2014-06-30 19:43:45 +08:00
& EX ( func ) - > op_array , execute_data TSRMLS_CC ) ;
2008-03-28 22:35:01 +08:00
2014-06-30 19:43:45 +08:00
brk_opline = EX ( func ) - > op_array . opcodes + el - > brk ;
2008-03-28 22:35:01 +08:00
2014-06-05 22:42:17 +08:00
if ( brk_opline - > opcode = = ZEND_SWITCH_FREE ) {
if ( ! ( brk_opline - > extended_value & EXT_TYPE_FREE_ON_RETURN ) ) {
zval_ptr_dtor ( EX_VAR ( brk_opline - > op1 . var ) ) ;
}
} else if ( brk_opline - > opcode = = ZEND_FREE ) {
if ( ! ( brk_opline - > extended_value & EXT_TYPE_FREE_ON_RETURN ) ) {
zval_dtor ( EX_VAR ( brk_opline - > op1 . var ) ) ;
}
2008-03-28 22:35:01 +08:00
}
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 ;
2014-04-02 04:48:26 +08:00
zval * result = EX_VAR ( opline - > result . var ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-04-30 22:32:42 +08:00
fast_equal_function ( result ,
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR ( BP_VAR_R ) TSRMLS_CC ) ;
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 ( ) ;
}
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 ( ) ;
2014-02-10 14:04:30 +08:00
zval_ptr_dtor ( EX_VAR ( opline - > op1 . 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 ( 68 , ZEND_NEW , ANY , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2014-02-10 14:04:30 +08:00
zval object_zval ;
2005-06-10 15:56:40 +08:00
zend_function * constructor ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-02-10 14:04:30 +08:00
if ( UNEXPECTED ( ( Z_CE_P ( EX_VAR ( opline - > op1 . var ) ) - > ce_flags & ( ZEND_ACC_INTERFACE | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS ) ) ! = 0 ) ) {
if ( Z_CE_P ( EX_VAR ( opline - > op1 . var ) ) - > ce_flags & ZEND_ACC_INTERFACE ) {
zend_error_noreturn ( E_ERROR , " Cannot instantiate interface %s " , Z_CE_P ( EX_VAR ( opline - > op1 . var ) ) - > name - > val ) ;
} else if ( ( Z_CE_P ( EX_VAR ( opline - > op1 . var ) ) - > ce_flags & ZEND_ACC_TRAIT ) = = ZEND_ACC_TRAIT ) {
zend_error_noreturn ( E_ERROR , " Cannot instantiate trait %s " , Z_CE_P ( EX_VAR ( opline - > op1 . var ) ) - > name - > val ) ;
2004-10-23 05:42:14 +08:00
} else {
2014-02-10 14:04:30 +08:00
zend_error_noreturn ( E_ERROR , " Cannot instantiate abstract class %s " , Z_CE_P ( EX_VAR ( opline - > op1 . var ) ) - > name - > val ) ;
2004-10-23 05:42:14 +08:00
}
}
2014-02-10 14:04:30 +08:00
object_init_ex ( & object_zval , Z_CE_P ( EX_VAR ( opline - > op1 . var ) ) ) ;
2014-03-28 06:11:22 +08:00
constructor = Z_OBJ_HT ( object_zval ) - > get_constructor ( Z_OBJ ( object_zval ) TSRMLS_CC ) ;
2005-06-10 15:56:40 +08:00
if ( constructor = = NULL ) {
if ( RETURN_VALUE_USED ( opline ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_COPY_VALUE ( EX_VAR ( opline - > result . var ) , & object_zval ) ;
2005-06-10 15:56:40 +08:00
} else {
zval_ptr_dtor ( & object_zval ) ;
}
2014-06-11 15:39:42 +08:00
ZEND_VM_JMP ( opline - > op2 . jmp_addr ) ;
2005-06-10 15:56:40 +08:00
} else {
2014-06-30 19:43:45 +08:00
/* We are not handling overloaded classes right now */
EX ( call ) = zend_vm_stack_push_call_frame (
constructor , opline - > extended_value ,
RETURN_VALUE_USED ( opline ) ?
ZEND_CALL_CTOR : ( ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_UNUSED ) ,
Z_CE_P ( EX_VAR ( opline - > op1 . var ) ) ,
Z_OBJ ( object_zval ) ,
EX ( call ) TSRMLS_CC ) ;
2012-11-30 17:39:23 +08:00
2007-12-14 22:14:50 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , & object_zval ) ;
2007-12-14 22:14:50 +08:00
}
2006-05-12 05:07:39 +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 ( ) ;
2014-06-16 17:08:48 +08:00
obj = GET_OP1_OBJ_ZVAL_PTR_DEREF ( BP_VAR_R ) ;
2010-04-20 19:16:39 +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 ( obj ) ! = IS_OBJECT ) ) {
2013-02-16 22:22:22 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
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 ) {
2014-02-22 00:44:26 +08:00
zend_error_noreturn ( E_ERROR , " Trying to clone an uncloneable object of class %s " , ce - > name - > val ) ;
2006-07-27 18:44:03 +08:00
} 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.
*/
2014-07-04 21:03:44 +08:00
if ( UNEXPECTED ( ce ! = EX ( scope ) ) ) {
zend_error_noreturn ( E_ERROR , " Call to private %s::__clone() from context '%s' " , ce - > name - > val , EX ( scope ) ? EX ( scope ) - > name - > val : " " ) ;
2004-10-23 05:42:14 +08:00
}
} else if ( ( clone - > common . fn_flags & ZEND_ACC_PROTECTED ) ) {
/* Ensure that if we're calling a protected function, we're allowed to do so.
*/
2014-07-04 21:03:44 +08:00
if ( UNEXPECTED ( ! zend_check_protected ( zend_get_function_root_class ( clone ) , EX ( scope ) ) ) ) {
zend_error_noreturn ( E_ERROR , " Call to protected %s::__clone() from context '%s' " , ce - > name - > val , EX ( scope ) ? EX ( scope ) - > name - > val : " " ) ;
2004-10-23 05:42:14 +08:00
}
}
}
2010-04-20 19:16:39 +08:00
if ( EXPECTED ( EG ( exception ) = = NULL ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_OBJ ( EX_VAR ( opline - > result . var ) , clone_call ( obj TSRMLS_CC ) ) ;
2010-04-20 19:16:39 +08:00
if ( ! RETURN_VALUE_USED ( opline ) | | UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2014-02-10 14:04:30 +08:00
zval_ptr_dtor ( EX_VAR ( opline - > result . var ) ) ;
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 ;
2014-04-17 19:40:45 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ) {
c = CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ;
} else if ( ( c = zend_quick_get_constant ( opline - > op2 . zv + 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 ) ;
2014-02-10 14:04:30 +08:00
ZVAL_STRINGL ( EX_VAR ( opline - > result . var ) , actual , Z_STRLEN_P ( opline - > op2 . zv ) - ( actual - Z_STRVAL_P ( opline - > op2 . zv ) ) ) ;
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 {
2014-04-17 19:40:45 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) , c ) ;
2004-10-23 05:42:14 +08:00
}
2014-02-10 14:04:30 +08:00
retval = EX_VAR ( opline - > result . var ) ;
2014-06-05 20:04:11 +08:00
ZVAL_COPY_VALUE ( retval , & c - > value ) ;
if ( Z_OPT_COPYABLE_P ( retval ) | | Z_OPT_REFCOUNTED_P ( retval ) ) {
if ( Z_OPT_COPYABLE_P ( retval ) & & ( c - > flags & CONST_PERSISTENT ) ) {
zval_copy_ctor_func ( retval ) ;
} else {
Z_ADDREF_P ( retval ) ;
}
}
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 ;
2014-02-10 14:04:30 +08:00
zval * value ;
2007-10-03 14:49:15 +08:00
2007-09-29 03:52:53 +08:00
if ( OP1_TYPE = = IS_CONST ) {
2014-04-17 19:40:45 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ) {
value = CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ;
2014-05-29 17:17:33 +08:00
ZVAL_DEREF ( value ) ;
2014-02-10 14:04:30 +08:00
ZVAL_DUP ( EX_VAR ( opline - > result . var ) , value ) ;
2014-06-03 13:45:09 +08:00
ZEND_VM_C_GOTO ( constant_fetch_end ) ;
2014-04-17 19:40:45 +08:00
} else if ( CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op1 . zv ) ) ) {
ce = CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op1 . zv ) ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-04-17 19:40:45 +08:00
ce = zend_fetch_class_by_name ( Z_STR_P ( opline - > op1 . zv ) , opline - > op1 . zv + 1 , opline - > extended_value TSRMLS_CC ) ;
2013-07-14 11:47:06 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
2010-05-24 22:11:39 +08:00
if ( UNEXPECTED ( ce = = NULL ) ) {
2013-07-14 11:47:06 +08:00
zend_error_noreturn ( E_ERROR , " Class '%s' not found " , Z_STRVAL_P ( opline - > op1 . zv ) ) ;
2010-05-24 22:11:39 +08:00
}
2014-04-17 19:40:45 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( opline - > op1 . zv ) , ce ) ;
2007-09-29 03:52:53 +08:00
}
} else {
2014-02-10 14:04:30 +08:00
ce = Z_CE_P ( EX_VAR ( opline - > op1 . var ) ) ;
2014-04-17 19:40:45 +08:00
if ( ( value = CACHED_POLYMORPHIC_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) , ce ) ) ! = NULL ) {
2014-05-29 06:02:13 +08:00
ZVAL_DEREF ( value ) ;
2014-02-10 14:04:30 +08:00
ZVAL_DUP ( EX_VAR ( opline - > result . var ) , value ) ;
2014-06-03 13:45:09 +08:00
ZEND_VM_C_GOTO ( constant_fetch_end ) ;
2010-05-24 22:11:39 +08:00
}
2007-09-29 03:52:53 +08:00
}
2004-10-23 05:42:14 +08:00
2014-02-10 14:04:30 +08:00
if ( EXPECTED ( ( value = zend_hash_find ( & ce - > constants_table , Z_STR_P ( opline - > op2 . zv ) ) ) ! = NULL ) ) {
2014-05-29 06:02:13 +08:00
ZVAL_DEREF ( value ) ;
2014-04-04 07:55:27 +08:00
if ( Z_CONSTANT_P ( value ) ) {
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 ;
2014-04-12 01:18:58 +08:00
zval_update_constant ( value , 1 TSRMLS_CC ) ;
2007-09-29 03:52:53 +08:00
EG ( scope ) = old_scope ;
}
2010-05-24 22:11:39 +08:00
if ( OP1_TYPE = = IS_CONST ) {
2014-04-17 19:40:45 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) , value ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-04-17 19:40:45 +08:00
CACHE_POLYMORPHIC_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) , ce , value ) ;
2010-05-24 22:11:39 +08:00
}
2014-02-10 14:04:30 +08:00
ZVAL_DUP ( EX_VAR ( opline - > result . var ) , value ) ;
2013-12-17 15:37:10 +08:00
} else if ( Z_STRLEN_P ( opline - > op2 . zv ) = = sizeof ( " class " ) - 1 & & memcmp ( Z_STRVAL_P ( opline - > op2 . zv ) , " class " , sizeof ( " class " ) - 1 ) = = 0 ) {
2013-01-19 08:00:47 +08:00
/* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */
2014-02-10 14:04:30 +08:00
ZVAL_STR ( EX_VAR ( opline - > result . var ) , ce - > name ) ;
STR_ADDREF ( ce - > name ) ;
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
}
2004-10-23 05:42:14 +08:00
}
2014-06-03 13:45:09 +08:00
ZEND_VM_C_LABEL ( constant_fetch_end ) :
2014-04-12 00:21:46 +08:00
CHECK_EXCEPTION ( ) ;
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 ;
2014-03-09 19:42:08 +08:00
zval * expr_ptr , new_expr ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-04-23 06:47:41 +08:00
if ( ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) & &
( opline - > extended_value & ZEND_ARRAY_ELEMENT_REF ) ) {
2014-03-04 16:27:50 +08:00
expr_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2014-02-10 14:04:30 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( expr_ptr ) = = IS_STR_OFFSET ) ) {
2010-10-22 19:05:22 +08:00
zend_error_noreturn ( E_ERROR , " Cannot create references to/from string offsets " ) ;
}
2014-06-05 20:04:11 +08:00
ZVAL_MAKE_REF ( expr_ptr ) ;
2014-03-14 02:07:37 +08:00
Z_ADDREF_P ( expr_ptr ) ;
2014-04-23 06:47:41 +08:00
FREE_OP1_VAR_PTR ( ) ;
2004-10-23 05:42:14 +08:00
} else {
2014-04-15 05:16:09 +08:00
expr_ptr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2010-04-20 19:16:39 +08:00
if ( IS_OP1_TMP_FREE ( ) ) { /* temporary variable */
2014-02-10 14:04:30 +08:00
ZVAL_COPY_VALUE ( & new_expr , expr_ptr ) ;
expr_ptr = & new_expr ;
2014-03-09 19:42:08 +08:00
} else if ( OP1_TYPE = = IS_CONST ) {
2014-06-03 06:43:53 +08:00
if ( ! Z_IMMUTABLE_P ( expr_ptr ) ) {
ZVAL_DUP ( & new_expr , expr_ptr ) ;
expr_ptr = & new_expr ;
}
2014-03-09 19:42:08 +08:00
} else if ( Z_ISREF_P ( expr_ptr ) ) {
ZVAL_DUP ( & new_expr , Z_REFVAL_P ( expr_ptr ) ) ;
2014-02-10 14:04:30 +08:00
expr_ptr = & new_expr ;
2013-05-17 17:15:09 +08:00
FREE_OP1_IF_VAR ( ) ;
2014-02-21 23:19:52 +08:00
} else if ( OP1_TYPE = = IS_CV & & Z_REFCOUNTED_P ( expr_ptr ) ) {
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 ;
2014-03-06 18:23:16 +08:00
zval * offset = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2014-04-23 06:47:41 +08:00
zend_string * str ;
2010-04-20 19:16:39 +08:00
ulong hval ;
2011-03-16 13:25:02 +08:00
2014-03-26 22:07:31 +08:00
ZEND_VM_C_LABEL ( add_again ) :
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 :
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 ) :
2014-02-10 14:04:30 +08:00
zend_hash_index_update ( Z_ARRVAL_P ( EX_VAR ( opline - > result . var ) ) , hval , expr_ptr ) ;
2004-10-23 05:42:14 +08:00
break ;
case IS_STRING :
2014-04-23 06:47:41 +08:00
str = Z_STR_P ( offset ) ;
2014-02-10 14:04:30 +08:00
if ( OP2_TYPE ! = IS_CONST ) {
2014-06-03 17:10:42 +08:00
if ( ZEND_HANDLE_NUMERIC ( str , hval ) ) {
ZEND_VM_C_GOTO ( num_index ) ;
}
2010-04-20 18:57:45 +08:00
}
2014-04-23 06:47:41 +08:00
ZEND_VM_C_LABEL ( str_index ) :
zend_hash_update ( Z_ARRVAL_P ( EX_VAR ( opline - > result . var ) ) , str , expr_ptr ) ;
2004-10-23 05:42:14 +08:00
break ;
case IS_NULL :
2014-04-23 06:47:41 +08:00
str = STR_EMPTY_ALLOC ( ) ;
ZEND_VM_C_GOTO ( str_index ) ;
2014-04-30 22:32:42 +08:00
case IS_FALSE :
hval = 0 ;
ZEND_VM_C_GOTO ( num_index ) ;
case IS_TRUE :
hval = 1 ;
ZEND_VM_C_GOTO ( num_index ) ;
2014-03-06 18:23:16 +08:00
case IS_REFERENCE :
offset = Z_REFVAL_P ( offset ) ;
2014-03-26 22:07:31 +08:00
ZEND_VM_C_GOTO ( add_again ) ;
2014-03-06 18:23:16 +08:00
break ;
2004-10-23 05:42:14 +08:00
default :
zend_error ( E_WARNING , " Illegal offset type " ) ;
2014-02-10 14:04:30 +08:00
zval_ptr_dtor ( expr_ptr ) ;
2004-10-23 05:42:14 +08:00
/* do nothing */
break ;
}
FREE_OP2 ( ) ;
} else {
2014-02-10 14:04:30 +08:00
zend_hash_next_index_insert ( Z_ARRVAL_P ( EX_VAR ( opline - > result . var ) ) , expr_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 ( 71 , ZEND_INIT_ARRAY , CONST | TMP | VAR | UNUSED | CV , CONST | TMP | VAR | UNUSED | CV )
{
2014-04-23 06:47:41 +08:00
zval * array ;
zend_uint size ;
2010-04-20 19:16:39 +08:00
USE_OPLINE
2006-09-18 22:23:52 +08:00
2014-04-23 06:47:41 +08:00
array = EX_VAR ( opline - > result . var ) ;
if ( OP1_TYPE ! = IS_UNUSED ) {
size = opline - > extended_value > > ZEND_ARRAY_SIZE_SHIFT ;
} else {
size = 0 ;
}
ZVAL_NEW_ARR ( array ) ;
zend_hash_init ( Z_ARRVAL_P ( array ) , size , NULL , ZVAL_PTR_DTOR , 0 ) ;
2014-04-23 03:33:49 +08:00
if ( OP1_TYPE ! = IS_UNUSED ) {
/* Explicitly initialize array as not-packed if flag is set */
2014-04-23 06:47:41 +08:00
if ( opline - > extended_value & ZEND_ARRAY_NOT_PACKED ) {
zend_hash_real_init ( Z_ARRVAL_P ( array ) , 0 ) ;
2014-04-23 03:33:49 +08:00
}
}
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 ;
2014-02-10 14:04:30 +08:00
zval * result = EX_VAR ( opline - > result . var ) ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-06-05 20:04:11 +08:00
expr = GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ;
2014-03-06 18:23:16 +08:00
2004-10-23 05:42:14 +08:00
switch ( opline - > extended_value ) {
case IS_NULL :
2014-04-26 19:17:26 +08:00
/* This code is taken from convert_to_null. However, it does not seems very useful,
* because a conversion to null always results in the same value . This could only
* be relevant if a cast_object handler for IS_NULL has some kind of side - effect . */
#if 0
2014-04-25 21:41:23 +08:00
if ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) {
ZVAL_DEREF ( expr ) ;
}
if ( Z_TYPE_P ( expr ) = = IS_OBJECT & & Z_OBJ_HT_P ( expr ) - > cast_object ) {
if ( Z_OBJ_HT_P ( expr ) - > cast_object ( expr , result , IS_NULL TSRMLS_CC ) = = SUCCESS ) {
break ;
}
}
2014-04-26 19:17:26 +08:00
# endif
2014-04-25 21:41:23 +08:00
2014-04-25 21:21:26 +08:00
ZVAL_NULL ( result ) ;
2004-10-23 05:42:14 +08:00
break ;
2014-04-30 22:32:42 +08:00
case _IS_BOOL :
2014-04-25 21:21:26 +08:00
ZVAL_BOOL ( result , zend_is_true ( expr TSRMLS_CC ) ) ;
2004-10-23 05:42:14 +08:00
break ;
case IS_LONG :
2014-04-25 21:21:26 +08:00
ZVAL_LONG ( result , zval_get_long ( expr ) ) ;
2004-10-23 05:42:14 +08:00
break ;
case IS_DOUBLE :
2014-04-25 21:21:26 +08:00
ZVAL_DOUBLE ( result , zval_get_double ( expr ) ) ;
2004-10-23 05:42:14 +08:00
break ;
2014-04-25 21:21:26 +08:00
case IS_STRING :
ZVAL_STR ( result , zval_get_string ( expr ) ) ;
break ;
default :
/* If value is already of correct type, return it directly */
if ( Z_TYPE_P ( expr ) = = opline - > extended_value ) {
2010-04-20 19:16:39 +08:00
ZVAL_COPY_VALUE ( result , expr ) ;
2014-04-25 21:21:26 +08:00
if ( OP1_TYPE = = IS_CONST ) {
2014-06-05 20:04:11 +08:00
if ( UNEXPECTED ( Z_OPT_COPYABLE_P ( result ) ) ) {
zval_copy_ctor_func ( result ) ;
}
} else if ( OP1_TYPE ! = IS_TMP_VAR ) {
2014-04-25 21:21:26 +08:00
if ( Z_OPT_REFCOUNTED_P ( expr ) ) Z_ADDREF_P ( expr ) ;
2007-10-03 16:02:36 +08:00
}
2014-04-25 21:21:26 +08:00
2014-06-05 20:04:11 +08:00
FREE_OP1 ( ) ;
2014-04-25 21:21:26 +08:00
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2004-10-23 05:42:14 +08:00
}
2014-04-25 21:21:26 +08:00
if ( opline - > extended_value = = IS_ARRAY ) {
2014-06-05 20:04:11 +08:00
if ( Z_TYPE_P ( expr ) ! = IS_OBJECT ) {
ZVAL_NEW_ARR ( result ) ;
zend_hash_init ( Z_ARRVAL_P ( result ) , 8 , NULL , ZVAL_PTR_DTOR , 0 ) ;
if ( Z_TYPE_P ( expr ) ! = IS_NULL ) {
expr = zend_hash_index_add_new ( Z_ARRVAL_P ( result ) , 0 , expr ) ;
if ( OP1_TYPE = = IS_CONST ) {
if ( UNEXPECTED ( Z_OPT_COPYABLE_P ( expr ) ) ) {
zval_copy_ctor_func ( expr ) ;
}
} else if ( OP1_TYPE ! = IS_TMP_VAR ) {
if ( Z_OPT_REFCOUNTED_P ( expr ) ) Z_ADDREF_P ( expr ) ;
}
}
} else {
ZVAL_COPY_VALUE ( result , expr ) ;
if ( ! IS_OP1_TMP_FREE ( ) ) {
zval_opt_copy_ctor ( result ) ;
}
convert_to_array ( result ) ;
}
2014-04-25 21:21:26 +08:00
} else {
2014-06-05 20:04:11 +08:00
if ( Z_TYPE_P ( expr ) ! = IS_ARRAY ) {
object_init ( result ) ;
if ( Z_TYPE_P ( expr ) ! = IS_NULL ) {
expr = zend_hash_str_add_new ( Z_OBJPROP_P ( result ) , " scalar " , sizeof ( " scalar " ) - 1 , expr ) ;
if ( OP1_TYPE = = IS_CONST ) {
if ( UNEXPECTED ( Z_OPT_COPYABLE_P ( expr ) ) ) {
zval_copy_ctor_func ( expr ) ;
}
} else if ( OP1_TYPE ! = IS_TMP_VAR ) {
if ( Z_OPT_REFCOUNTED_P ( expr ) ) Z_ADDREF_P ( expr ) ;
}
}
} else {
ZVAL_COPY_VALUE ( result , expr ) ;
if ( ! IS_OP1_TMP_FREE ( ) ) {
zval_opt_copy_ctor ( result ) ;
}
convert_to_object ( result ) ;
}
2014-04-25 21:21:26 +08:00
}
FREE_OP1_IF_VAR ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2004-10-23 05:42:14 +08:00
}
2014-04-25 21:21:26 +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 ( 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 ;
2014-02-10 14:04:30 +08:00
zval tmp_inc_filename ;
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 ) ;
2014-02-10 14:04:30 +08:00
ZVAL_UNDEF ( & tmp_inc_filename ) ;
2014-04-02 18:34:44 +08:00
if ( Z_TYPE_P ( inc_filename ) ! = IS_STRING ) {
2014-02-10 14:04:30 +08:00
ZVAL_DUP ( & tmp_inc_filename , 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 ) {
2014-02-21 21:23:13 +08:00
failure_retval = zend_hash_str_exists ( & EG ( included_files ) , resolved_path , strlen ( resolved_path ) ) ;
2011-06-07 05:28:16 +08:00
} 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 ) ;
}
2014-02-21 21:23:13 +08:00
if ( zend_hash_str_add_empty_element ( & EG ( included_files ) , file_handle . opened_path , strlen ( file_handle . opened_path ) ) ) {
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
}
2014-02-10 14:04:30 +08:00
if ( Z_TYPE ( tmp_inc_filename ) ! = IS_UNDEF ) {
2012-01-24 22:39:45 +08:00
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 ) ) {
2014-02-12 18:29:51 +08:00
zval * return_value = NULL ;
2014-07-07 19:50:44 +08:00
zend_execute_data * call ;
2014-02-12 18:29:51 +08:00
2010-04-20 19:16:39 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
2014-02-12 18:29:51 +08:00
return_value = EX_VAR ( opline - > result . var ) ;
2010-04-20 19:16:39 +08:00
}
2004-10-23 05:42:14 +08:00
2014-07-07 19:50:44 +08:00
call = zend_vm_stack_push_call_frame (
( zend_function * ) new_op_array , 0 , 0 , EX ( called_scope ) , Z_OBJ ( EG ( This ) ) , NULL TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
2014-07-04 22:03:45 +08:00
if ( EX ( symbol_table ) ) {
2014-07-07 19:50:44 +08:00
call - > symbol_table = EX ( symbol_table ) ;
2014-07-04 22:03:45 +08:00
} else {
2014-07-07 19:50:44 +08:00
call - > symbol_table = zend_rebuild_symbol_table ( TSRMLS_C ) ;
2008-04-29 16:15:20 +08:00
}
2014-07-07 19:50:44 +08:00
call - > prev_execute_data = execute_data ;
i_init_code_execute_data ( call , new_op_array , return_value , VM_FRAME_NESTED_CODE TSRMLS_CC ) ;
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 {
2014-07-07 19:50:44 +08:00
execute_ex ( call TSRMLS_CC ) ;
2008-06-11 21:18:41 +08:00
}
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 ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , failure_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 ;
2014-04-13 21:00:32 +08:00
zend_bool tmp_is_dup = 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 & &
OP2_TYPE = = IS_UNUSED & &
( opline - > extended_value & ZEND_QUICK_SET ) ) {
2014-04-09 14:47:24 +08:00
ZVAL_COPY_VALUE ( & tmp , EX_VAR ( opline - > op1 . var ) ) ;
2014-03-27 20:00:25 +08:00
ZVAL_UNDEF ( EX_VAR ( opline - > op1 . var ) ) ;
2014-04-09 14:47:24 +08:00
zval_ptr_dtor ( & tmp ) ;
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 ) {
2014-02-10 14:04:30 +08:00
ZVAL_DUP ( & tmp , varname ) ;
2004-10-23 05:42:14 +08:00
convert_to_string ( & tmp ) ;
varname = & tmp ;
2014-04-13 21:00:32 +08:00
tmp_is_dup = 1 ;
2008-05-12 17:09:05 +08:00
} else if ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) {
2014-04-13 21:00:32 +08:00
ZVAL_COPY ( & tmp , varname ) ;
varname = & tmp ;
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 ) {
2014-04-17 19:40:45 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ) {
ce = CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-04-17 19:40:45 +08:00
ce = zend_fetch_class_by_name ( Z_STR_P ( opline - > op2 . zv ) , opline - > op2 . zv + 1 , 0 TSRMLS_CC ) ;
2013-07-14 11:47:06 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2014-04-13 21:00:32 +08:00
if ( OP1_TYPE ! = IS_CONST & & tmp_is_dup ) {
2012-02-25 21:56:59 +08:00
zval_dtor ( & tmp ) ;
} else if ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) {
2014-04-13 21:00:32 +08:00
zval_ptr_dtor ( & tmp ) ;
2012-02-25 21:56:59 +08:00
}
FREE_OP1 ( ) ;
2013-07-14 11:47:06 +08:00
HANDLE_EXCEPTION ( ) ;
}
if ( UNEXPECTED ( ce = = NULL ) ) {
zend_error_noreturn ( E_ERROR , " Class '%s' not found " , Z_STRVAL_P ( opline - > op2 . zv ) ) ;
2012-02-25 21:56:59 +08:00
}
2014-04-17 19:40:45 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) , ce ) ;
2010-05-24 22:11:39 +08:00
}
2010-05-06 18:27:35 +08:00
} else {
2014-02-10 14:04:30 +08:00
ce = Z_CE_P ( EX_VAR ( opline - > op2 . var ) ) ;
2010-05-06 18:27:35 +08:00
}
2014-04-17 20:10:16 +08:00
zend_std_unset_static_property ( ce , Z_STR_P ( varname ) , ( ( OP1_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( varname ) : - 1 ) TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
} else {
2014-07-03 02:03:21 +08:00
target_symbol_table = zend_get_target_symbol_table ( execute_data , opline - > extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC ) ;
2014-03-26 22:07:31 +08:00
zend_hash_del_ind ( target_symbol_table , Z_STR_P ( varname ) ) ;
2004-10-23 05:42:14 +08:00
}
2014-04-13 21:00:32 +08:00
if ( OP1_TYPE ! = IS_CONST & & tmp_is_dup ) {
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 ) {
2014-04-13 21:00:32 +08:00
zval_ptr_dtor ( & tmp ) ;
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 ;
2014-02-10 14:04:30 +08:00
zval * container ;
2010-04-20 19:16:39 +08:00
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 ( ) ;
2014-03-04 16:27:50 +08:00
container = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_UNSET ) ;
2014-04-04 23:01:53 +08:00
if ( OP1_TYPE ! = IS_UNUSED ) {
2014-06-12 17:01:44 +08:00
ZVAL_DEREF ( container ) ;
SEPARATE_ZVAL_NOREF ( container ) ;
2011-04-25 15:50:07 +08:00
}
2010-04-20 19:16:39 +08:00
offset = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2011-03-16 13:25:02 +08:00
2014-04-04 23:01:53 +08:00
switch ( Z_TYPE_P ( container ) ) {
case IS_ARRAY : {
HashTable * ht = Z_ARRVAL_P ( container ) ;
2014-03-26 22:07:31 +08:00
ZEND_VM_C_LABEL ( offset_again ) :
2014-04-04 23:01:53 +08:00
switch ( Z_TYPE_P ( offset ) ) {
case IS_DOUBLE :
hval = zend_dval_to_lval ( Z_DVAL_P ( offset ) ) ;
zend_hash_index_del ( ht , hval ) ;
break ;
case IS_LONG :
hval = Z_LVAL_P ( offset ) ;
2014-04-30 22:32:42 +08:00
ZEND_VM_C_LABEL ( num_index_dim ) :
2014-04-04 23:01:53 +08:00
zend_hash_index_del ( ht , hval ) ;
break ;
case IS_STRING :
if ( OP2_TYPE = = IS_CV | | OP2_TYPE = = IS_VAR ) {
if ( Z_REFCOUNTED_P ( offset ) ) Z_ADDREF_P ( offset ) ;
}
if ( OP2_TYPE ! = IS_CONST ) {
2014-06-03 17:10:42 +08:00
if ( ZEND_HANDLE_NUMERIC ( Z_STR_P ( offset ) , hval ) ) {
ZEND_VM_C_GOTO ( numeric_index_dim ) ;
}
2014-04-04 23:01:53 +08:00
}
if ( ht = = & EG ( symbol_table ) . ht ) {
zend_delete_global_variable ( Z_STR_P ( offset ) TSRMLS_CC ) ;
} else {
zend_hash_del ( ht , Z_STR_P ( offset ) ) ;
}
if ( OP2_TYPE = = IS_CV | | OP2_TYPE = = IS_VAR ) {
zval_ptr_dtor ( offset ) ;
}
break ;
2014-04-30 22:32:42 +08:00
ZEND_VM_C_LABEL ( numeric_index_dim ) :
2014-04-04 23:01:53 +08:00
zend_hash_index_del ( ht , hval ) ;
if ( OP2_TYPE = = IS_CV | | OP2_TYPE = = IS_VAR ) {
zval_ptr_dtor ( offset ) ;
}
break ;
case IS_NULL :
zend_hash_del ( ht , STR_EMPTY_ALLOC ( ) ) ;
break ;
2014-04-30 22:32:42 +08:00
case IS_FALSE :
hval = 0 ;
ZEND_VM_C_GOTO ( num_index_dim ) ;
case IS_TRUE :
hval = 1 ;
ZEND_VM_C_GOTO ( num_index_dim ) ;
case IS_RESOURCE :
hval = Z_RES_HANDLE_P ( offset ) ;
ZEND_VM_C_GOTO ( num_index_dim ) ;
2014-04-04 23:01:53 +08:00
case IS_REFERENCE :
offset = Z_REFVAL_P ( offset ) ;
ZEND_VM_C_GOTO ( offset_again ) ;
break ;
default :
zend_error ( E_WARNING , " Illegal offset type in unset " ) ;
break ;
2004-10-23 05:42:14 +08:00
}
2014-04-04 23:01:53 +08:00
FREE_OP2 ( ) ;
break ;
2005-06-16 20:17:39 +08:00
}
2014-04-04 23:01:53 +08:00
case IS_OBJECT :
if ( UNEXPECTED ( Z_OBJ_HT_P ( container ) - > unset_dimension = = NULL ) ) {
zend_error_noreturn ( E_ERROR , " Cannot use object as array " ) ;
}
2014-04-16 05:45:40 +08:00
//??? if (OP2_TYPE == IS_CONST) {
//??? zval_copy_ctor(offset);
2014-04-04 23:01:53 +08:00
//??? }
Z_OBJ_HT_P ( container ) - > unset_dimension ( container , offset TSRMLS_CC ) ;
2014-04-16 05:45:40 +08:00
FREE_OP2 ( ) ;
2014-04-04 23:01:53 +08:00
break ;
case IS_STRING :
case IS_STR_OFFSET :
zend_error_noreturn ( E_ERROR , " Cannot unset string offsets " ) ;
ZEND_VM_CONTINUE ( ) ; /* bailed out before */
default :
FREE_OP2 ( ) ;
break ;
2005-06-16 20:17:39 +08:00
}
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 ;
2014-02-10 14:04:30 +08:00
zval * container ;
2010-04-20 19:16:39 +08:00
zval * offset ;
SAVE_OPLINE ( ) ;
2014-03-04 16:27:50 +08:00
container = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_UNSET ) ;
2014-04-04 23:01:53 +08:00
if ( OP1_TYPE = = IS_VAR & & Z_TYPE_P ( container ) = = IS_STR_OFFSET ) {
zend_error_noreturn ( E_ERROR , " Cannot unset string offsets " ) ;
}
2010-04-20 19:16:39 +08:00
offset = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2005-06-16 20:17:39 +08:00
2014-04-04 23:01:53 +08:00
ZVAL_DEREF ( container ) ;
if ( Z_TYPE_P ( container ) = = IS_OBJECT ) {
if ( Z_OBJ_HT_P ( container ) - > unset_property ) {
2014-04-17 20:10:16 +08:00
Z_OBJ_HT_P ( container ) - > unset_property ( container , offset , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( offset ) : - 1 ) TSRMLS_CC ) ;
2005-06-16 20:17:39 +08:00
} else {
2014-04-04 23:01:53 +08:00
zend_error ( E_NOTICE , " Trying to unset property of non-object " ) ;
2004-10-23 05:42:14 +08:00
}
}
2014-04-16 01:56:30 +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 ;
2014-05-29 22:21:56 +08:00
zval * array_ptr , * array_ref , iterator , tmp ;
2004-10-23 05:42:14 +08:00
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 ) ) {
2014-03-06 03:22:50 +08:00
array_ptr = array_ref = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_R ) ;
2014-03-27 17:39:09 +08:00
ZVAL_DEREF ( array_ptr ) ;
if ( Z_TYPE_P ( array_ptr ) = = IS_ARRAY ) {
if ( ! Z_ISREF_P ( array_ref ) ) {
2014-06-05 20:04:11 +08:00
SEPARATE_ZVAL_NOREF ( array_ptr ) ;
2014-03-27 17:39:09 +08:00
array_ref = array_ptr ;
if ( opline - > extended_value & ZEND_FE_FETCH_BYREF ) {
ZVAL_NEW_REF ( array_ptr , array_ptr ) ;
array_ref = array_ptr ;
array_ptr = Z_REFVAL_P ( array_ptr ) ;
}
2014-05-29 22:21:56 +08:00
} else if ( Z_IMMUTABLE_P ( array_ptr ) ) {
zval_copy_ctor ( array_ptr ) ;
2014-03-27 17:39:09 +08:00
}
if ( Z_REFCOUNTED_P ( array_ref ) ) Z_ADDREF_P ( array_ref ) ;
2014-02-10 14:04:30 +08:00
} else if ( Z_TYPE_P ( array_ptr ) = = IS_OBJECT ) {
if ( Z_OBJ_HT_P ( array_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 " ) ;
2014-06-11 15:39:42 +08:00
ZEND_VM_JMP ( opline - > op2 . jmp_addr ) ;
2005-06-28 18:49:56 +08:00
}
2006-05-12 05:07:39 +08:00
2014-02-10 14:04:30 +08:00
ce = Z_OBJCE_P ( array_ptr ) ;
2004-10-23 05:42:14 +08:00
if ( ! ce | | ce - > get_iterator = = NULL ) {
2014-03-06 03:22:50 +08:00
if ( ! Z_ISREF_P ( array_ref ) ) {
2014-06-05 20:04:11 +08:00
SEPARATE_ZVAL_NOREF ( array_ptr ) ;
2014-02-26 03:26:04 +08:00
}
2014-02-10 14:04:30 +08:00
Z_ADDREF_P ( array_ptr ) ;
2004-10-23 05:42:14 +08:00
}
2014-03-06 03:22:50 +08:00
array_ref = array_ptr ;
2004-10-23 05:42:14 +08:00
} else {
2014-03-06 03:22:50 +08:00
if ( Z_REFCOUNTED_P ( array_ref ) ) Z_ADDREF_P ( array_ref ) ;
2004-10-23 05:42:14 +08:00
}
} else {
2014-03-06 03:22:50 +08:00
array_ptr = array_ref = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-03-27 17:39:09 +08:00
ZVAL_DEREF ( array_ptr ) ;
2004-10-23 05:42:14 +08:00
if ( IS_OP1_TMP_FREE ( ) ) { /* IS_TMP_VAR */
2014-02-10 14:04:30 +08:00
ZVAL_COPY_VALUE ( & 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 ) {
2014-03-06 03:22:50 +08:00
Z_DELREF_P ( array_ref ) ;
2009-08-17 15:40:43 +08:00
}
}
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 ) {
2013-05-17 17:15:09 +08:00
if ( OP1_TYPE = = IS_CV ) {
2014-03-06 03:22:50 +08:00
Z_ADDREF_P ( array_ref ) ;
2013-05-17 17:15:09 +08:00
}
2006-10-03 17:05:14 +08:00
}
2014-05-29 22:21:56 +08:00
} else if ( Z_IMMUTABLE_P ( array_ref ) ) {
if ( OP1_TYPE = = IS_CV ) {
zval_copy_ctor ( array_ref ) ;
Z_ADDREF_P ( array_ref ) ;
} else {
ZVAL_DUP ( & tmp , array_ref ) ;
array_ptr = array_ref = & tmp ;
}
2014-03-06 03:22:50 +08:00
} else if ( Z_REFCOUNTED_P ( array_ref ) ) {
2014-02-22 00:35:40 +08:00
if ( OP1_TYPE = = IS_CONST | |
( OP1_TYPE = = IS_CV & &
2014-03-06 03:22:50 +08:00
! Z_ISREF_P ( array_ref ) & &
Z_REFCOUNT_P ( array_ref ) > 1 ) | |
2014-02-22 00:35:40 +08:00
( OP1_TYPE = = IS_VAR & &
2014-03-06 03:22:50 +08:00
! Z_ISREF_P ( array_ref ) & &
Z_REFCOUNT_P ( array_ref ) > 2 ) ) {
2014-02-22 00:35:40 +08:00
if ( OP1_TYPE = = IS_VAR ) {
2014-03-06 03:22:50 +08:00
Z_DELREF_P ( array_ref ) ;
2014-02-22 00:35:40 +08:00
}
2014-03-06 03:22:50 +08:00
ZVAL_DUP ( & tmp , array_ref ) ;
array_ptr = array_ref = & tmp ;
2014-02-22 00:35:40 +08:00
} else if ( OP1_TYPE = = IS_CV ) {
2014-04-16 01:56:30 +08:00
if ( Z_ISREF_P ( array_ref ) & & Z_REFCOUNT_P ( array_ref ) = = 1 ) {
ZVAL_UNREF ( array_ref ) ;
array_ptr = array_ref ;
2014-03-12 16:07:03 +08:00
}
2014-05-29 22:21:56 +08:00
if ( Z_IMMUTABLE_P ( array_ptr ) ) {
zval_copy_ctor ( array_ptr ) ;
}
2014-03-19 21:00:28 +08:00
Z_ADDREF_P ( array_ref ) ;
2013-05-17 17:15:09 +08:00
}
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
2013-05-17 17:15:09 +08:00
if ( OP1_TYPE = = IS_VAR & & ! ( opline - > extended_value & ZEND_FE_RESET_VARIABLE ) ) {
FREE_OP1_IF_VAR ( ) ;
}
2010-04-20 19:16:39 +08:00
if ( iter & & EXPECTED ( EG ( exception ) = = NULL ) ) {
2014-04-11 22:16:03 +08:00
ZVAL_OBJ ( & iterator , & iter - > std ) ;
2014-03-06 03:22:50 +08:00
array_ptr = array_ref = & iterator ;
2004-10-23 05:42:14 +08:00
} else {
2013-05-17 17:15:09 +08:00
if ( OP1_TYPE = = IS_VAR & & opline - > extended_value & ZEND_FE_RESET_VARIABLE ) {
FREE_OP1_VAR_PTR ( ) ;
}
2005-01-25 18:40:51 +08:00
if ( ! EG ( exception ) ) {
2014-02-22 00:44:26 +08:00
zend_throw_exception_ex ( NULL , 0 TSRMLS_CC , " Object of type %s did not create an Iterator " , ce - > name - > val ) ;
2005-01-25 18:40:51 +08:00
}
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
}
}
2014-03-06 03:22:50 +08:00
ZVAL_COPY_VALUE ( EX_VAR ( opline - > result . var ) , array_ref ) ;
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 ) ) {
2014-03-06 03:22:50 +08:00
zval_ptr_dtor ( array_ref ) ;
2013-05-17 17:15:09 +08:00
if ( OP1_TYPE = = IS_VAR & & opline - > extended_value & ZEND_FE_RESET_VARIABLE ) {
FREE_OP1_VAR_PTR ( ) ;
}
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 ) ) {
2014-03-06 03:22:50 +08:00
zval_ptr_dtor ( array_ref ) ;
2013-05-17 17:15:09 +08:00
if ( OP1_TYPE = = IS_VAR & & opline - > extended_value & ZEND_FE_RESET_VARIABLE ) {
FREE_OP1_VAR_PTR ( ) ;
}
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 ) {
2014-02-10 14:04:30 +08:00
zend_object * zobj = Z_OBJ_P ( array_ptr ) ;
2005-02-05 22:01:59 +08:00
while ( zend_hash_has_more_elements ( fe_ht ) = = SUCCESS ) {
2014-02-10 14:04:30 +08:00
zend_string * str_key ;
2005-02-05 22:01:59 +08:00
ulong int_key ;
2006-05-12 05:07:39 +08:00
zend_uchar key_type ;
2014-04-08 03:14:17 +08:00
key_type = zend_hash_get_current_key ( fe_ht , & str_key , & int_key , 0 ) ;
2013-07-09 05:09:06 +08:00
if ( key_type ! = HASH_KEY_NON_EXISTENT & &
2006-12-26 03:23:03 +08:00
( key_type = = HASH_KEY_IS_LONG | |
2014-02-10 14:04:30 +08:00
zend_check_property_access ( zobj , str_key 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 ;
2014-03-13 21:01:28 +08:00
zend_hash_get_pointer ( fe_ht , ( HashPointer * ) EX_VAR ( ( opline + 2 ) - > op1 . var ) ) ;
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
}
2013-05-17 17:15:09 +08:00
if ( OP1_TYPE = = IS_VAR & & opline - > extended_value & ZEND_FE_RESET_VARIABLE ) {
FREE_OP1_VAR_PTR ( ) ;
}
2005-02-05 22:01:59 +08:00
if ( is_empty ) {
2014-06-11 15:39:42 +08:00
ZEND_VM_JMP ( opline - > op2 . jmp_addr ) ;
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 ;
2014-03-06 03:22:50 +08:00
zval * array , * array_ref ;
2014-02-10 14:04:30 +08:00
zval * value ;
2004-10-23 05:42:14 +08:00
HashTable * fe_ht ;
zend_object_iterator * iter = NULL ;
2013-02-17 02:13:36 +08:00
zval * key = NULL ;
2014-03-06 03:22:50 +08:00
array = array_ref = EX_VAR ( opline - > op1 . var ) ;
2014-06-05 20:04:11 +08:00
if ( Z_ISREF_P ( array ) ) {
array = Z_REFVAL_P ( array ) ;
// TODO: referenced value might be changed to different array ???
if ( Z_IMMUTABLE_P ( array ) ) {
zval_copy_ctor ( array ) ;
}
}
2013-02-17 02:13:36 +08:00
if ( opline - > extended_value & ZEND_FE_FETCH_WITH_KEY ) {
2014-02-10 14:04:30 +08:00
key = EX_VAR ( ( opline + 1 ) - > result . var ) ;
2013-02-17 02:13:36 +08:00
}
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() " ) ;
2014-06-11 15:39:42 +08:00
ZEND_VM_JMP ( opline - > op2 . jmp_addr ) ;
2004-10-23 05:42:14 +08:00
case ZEND_ITER_PLAIN_OBJECT : {
2014-02-10 14:04:30 +08:00
zend_object * zobj = Z_OBJ_P ( array ) ;
2013-02-17 02:13:36 +08:00
int key_type ;
2014-02-10 14:04:30 +08:00
zend_string * str_key ;
2013-02-17 02:13:36 +08:00
zend_ulong int_key ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
fe_ht = Z_OBJPROP_P ( array ) ;
2014-03-13 21:01:28 +08:00
zend_hash_set_pointer ( fe_ht , ( HashPointer * ) EX_VAR ( ( opline + 1 ) - > op1 . var ) ) ;
2014-03-26 22:07:31 +08:00
while ( 1 ) {
2014-02-10 14:04:30 +08:00
if ( ( value = zend_hash_get_current_data ( fe_ht ) ) = = NULL ) {
2004-10-23 05:42:14 +08:00
/* reached end of iteration */
2014-06-11 15:39:42 +08:00
ZEND_VM_JMP ( opline - > op2 . jmp_addr ) ;
2004-10-23 05:42:14 +08:00
}
2014-03-26 22:07:31 +08:00
if ( Z_TYPE_P ( value ) = = IS_INDIRECT ) {
value = Z_INDIRECT_P ( value ) ;
if ( Z_TYPE_P ( value ) = = IS_UNDEF ) {
zend_hash_move_forward ( fe_ht ) ;
continue ;
}
}
2014-04-08 03:14:17 +08:00
key_type = zend_hash_get_current_key ( fe_ht , & str_key , & int_key , 0 ) ;
2004-10-23 05:42:14 +08:00
zend_hash_move_forward ( fe_ht ) ;
2014-03-26 22:07:31 +08:00
if ( key_type = = HASH_KEY_IS_LONG | |
zend_check_property_access ( zobj , str_key TSRMLS_CC ) = = SUCCESS ) {
break ;
}
}
2013-02-17 02:13:36 +08:00
if ( key ) {
if ( key_type = = HASH_KEY_IS_LONG ) {
ZVAL_LONG ( key , int_key ) ;
} else {
2014-02-25 21:56:03 +08:00
const char * class_name , * prop_name ;
int prop_name_len ;
zend_unmangle_property_name_ex (
str_key - > val , str_key - > len , & class_name , & prop_name , & prop_name_len
) ;
ZVAL_STRINGL ( key , prop_name , prop_name_len ) ;
2013-02-17 02:13:36 +08:00
}
2004-10-23 05:42:14 +08:00
}
2013-02-17 02:13:36 +08:00
2014-03-13 21:01:28 +08:00
zend_hash_get_pointer ( fe_ht , ( HashPointer * ) EX_VAR ( ( opline + 1 ) - > op1 . var ) ) ;
2004-10-23 05:42:14 +08:00
break ;
}
case ZEND_ITER_PLAIN_ARRAY :
2010-04-20 19:16:39 +08:00
fe_ht = Z_ARRVAL_P ( array ) ;
2014-03-13 21:01:28 +08:00
zend_hash_set_pointer ( fe_ht , ( HashPointer * ) EX_VAR ( ( opline + 1 ) - > op1 . var ) ) ;
2014-02-10 14:04:30 +08:00
if ( ( value = zend_hash_get_current_data ( fe_ht ) ) = = NULL ) {
2004-10-23 05:42:14 +08:00
/* reached end of iteration */
2014-06-11 15:39:42 +08:00
ZEND_VM_JMP ( opline - > op2 . jmp_addr ) ;
2004-10-23 05:42:14 +08:00
}
2013-02-17 02:13:36 +08:00
if ( key ) {
zend_hash_get_current_key_zval ( fe_ht , key ) ;
2004-10-23 05:42:14 +08:00
}
zend_hash_move_forward ( fe_ht ) ;
2014-03-13 21:01:28 +08:00
zend_hash_get_pointer ( fe_ht , ( HashPointer * ) EX_VAR ( ( opline + 1 ) - > op1 . var ) ) ;
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 ) ) {
2014-03-06 03:22:50 +08:00
zval_ptr_dtor ( array_ref ) ;
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 ) ) {
2014-03-06 03:22:50 +08:00
zval_ptr_dtor ( array_ref ) ;
2010-04-20 19:16:39 +08:00
HANDLE_EXCEPTION ( ) ;
2005-04-27 14:47:08 +08:00
}
2014-06-11 15:39:42 +08:00
ZEND_VM_JMP ( opline - > op2 . jmp_addr ) ;
2004-10-23 05:42:14 +08:00
}
2014-02-10 14:04:30 +08:00
value = iter - > funcs - > get_current_data ( iter TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2014-03-06 03:22:50 +08:00
zval_ptr_dtor ( array_ref ) ;
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 */
2014-06-11 15:39:42 +08:00
ZEND_VM_JMP ( opline - > op2 . jmp_addr ) ;
2004-10-23 05:42:14 +08:00
}
2013-02-17 02:13:36 +08:00
if ( key ) {
2004-10-23 05:42:14 +08:00
if ( iter - > funcs - > get_current_key ) {
2013-02-17 02:13:36 +08:00
iter - > funcs - > get_current_key ( iter , key TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2014-03-06 03:22:50 +08:00
zval_ptr_dtor ( array_ref ) ;
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 {
2013-02-17 02:13:36 +08:00
ZVAL_LONG ( key , iter - > index ) ;
2004-10-23 05:42:14 +08:00
}
}
break ;
}
if ( opline - > extended_value & ZEND_FE_FETCH_BYREF ) {
2014-06-05 20:04:11 +08:00
ZVAL_MAKE_REF ( value ) ;
Z_ADDREF_P ( value ) ;
ZVAL_REF ( EX_VAR ( opline - > result . var ) , Z_REF_P ( value ) ) ;
} else {
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , value ) ;
2005-02-08 00:09:54 +08:00
}
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
2014-02-10 14:04:30 +08:00
zval * value ;
2004-10-23 05:42:14 +08:00
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 ) ) {
2014-03-27 20:00:25 +08:00
if ( Z_TYPE_P ( EX_VAR ( opline - > op1 . var ) ) ! = IS_UNDEF ) {
value = EX_VAR ( opline - > op1 . var ) ;
2014-03-27 17:39:09 +08:00
ZVAL_DEREF ( value ) ;
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 ) {
2014-02-10 14:04:30 +08:00
ZVAL_DUP ( & tmp , varname ) ;
2008-04-29 16:15:20 +08:00
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 ) {
2014-04-17 19:40:45 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ) {
ce = CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-04-17 19:40:45 +08:00
ce = zend_fetch_class_by_name ( Z_STR_P ( opline - > op2 . zv ) , opline - > op2 . zv + 1 , 0 TSRMLS_CC ) ;
2012-02-25 21:56:59 +08:00
if ( UNEXPECTED ( ce = = NULL ) ) {
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-04-17 19:40:45 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) , ce ) ;
2010-05-24 22:11:39 +08:00
}
2010-05-06 18:27:35 +08:00
} else {
2014-02-10 14:04:30 +08:00
ce = Z_CE_P ( EX_VAR ( opline - > op2 . var ) ) ;
2010-05-06 18:27:35 +08:00
}
2014-04-17 20:10:16 +08:00
value = zend_std_get_static_property ( ce , Z_STR_P ( varname ) , 1 , ( ( OP1_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( varname ) : - 1 ) TSRMLS_CC ) ;
2008-04-29 16:15:20 +08:00
if ( ! value ) {
isset = 0 ;
}
} else {
2014-07-03 02:03:21 +08:00
target_symbol_table = zend_get_target_symbol_table ( execute_data , opline - > extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC ) ;
2014-02-10 14:04:30 +08:00
if ( ( value = zend_hash_find ( target_symbol_table , Z_STR_P ( varname ) ) ) = = NULL ) {
2008-04-29 16:15:20 +08:00
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 ) {
2014-02-10 14:04:30 +08:00
if ( isset & & Z_TYPE_P ( value ) ! = IS_NULL ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , 1 ) ;
2010-04-20 18:57:45 +08:00
} else {
2014-02-10 14:04:30 +08:00
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , 0 ) ;
2010-04-20 18:57:45 +08:00
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
2014-02-10 14:04:30 +08:00
if ( ! isset | | ! i_zend_is_true ( value TSRMLS_CC ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , 1 ) ;
2010-04-20 18:57:45 +08:00
} else {
2014-02-10 14:04:30 +08:00
ZVAL_BOOL ( EX_VAR ( opline - > result . 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 ( ) ;
}
2014-04-22 04:32:29 +08:00
ZEND_VM_HANDLER ( 115 , ZEND_ISSET_ISEMPTY_DIM_OBJ , 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
2010-07-16 19:44:30 +08:00
zend_free_op free_op1 , free_op2 ;
2013-10-28 18:44:07 +08:00
zval * container ;
2014-04-07 18:56:34 +08:00
int result ;
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 ( ) ;
2014-03-27 17:39:09 +08:00
container = GET_OP1_OBJ_ZVAL_PTR_DEREF ( BP_VAR_IS ) ;
2010-07-16 19:44:30 +08:00
offset = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2005-06-03 19:16:19 +08:00
2014-04-22 04:32:29 +08:00
if ( Z_TYPE_P ( container ) = = IS_ARRAY ) {
2014-04-07 18:56:34 +08:00
HashTable * ht = Z_ARRVAL_P ( container ) ;
2014-06-05 22:42:17 +08:00
zval * value ;
2014-04-07 18:56:34 +08:00
zend_string * str ;
2004-10-23 05:42:14 +08:00
2014-03-26 22:07:31 +08:00
ZEND_VM_C_LABEL ( isset_again ) :
2014-06-05 22:42:17 +08:00
if ( EXPECTED ( Z_TYPE_P ( offset ) = = IS_STRING ) ) {
str = Z_STR_P ( offset ) ;
if ( OP2_TYPE ! = IS_CONST ) {
if ( ZEND_HANDLE_NUMERIC ( str , hval ) ) {
ZEND_VM_C_GOTO ( num_index_prop ) ;
2010-04-20 18:57:45 +08:00
}
2014-06-05 22:42:17 +08:00
}
2014-04-07 18:56:34 +08:00
ZEND_VM_C_LABEL ( str_index_prop ) :
2014-06-05 22:42:17 +08:00
value = zend_hash_find_ind ( ht , str ) ;
} else if ( EXPECTED ( Z_TYPE_P ( offset ) = = IS_LONG ) ) {
hval = Z_LVAL_P ( offset ) ;
ZEND_VM_C_LABEL ( num_index_prop ) :
value = zend_hash_index_find ( ht , hval ) ;
} else {
switch ( Z_TYPE_P ( offset ) ) {
case IS_DOUBLE :
hval = zend_dval_to_lval ( Z_DVAL_P ( offset ) ) ;
ZEND_VM_C_GOTO ( num_index_prop ) ;
case IS_NULL :
str = STR_EMPTY_ALLOC ( ) ;
ZEND_VM_C_GOTO ( str_index_prop ) ;
case IS_FALSE :
hval = 0 ;
ZEND_VM_C_GOTO ( num_index_prop ) ;
case IS_TRUE :
hval = 0 ;
ZEND_VM_C_GOTO ( num_index_prop ) ;
case IS_RESOURCE :
hval = Z_RES_HANDLE_P ( offset ) ;
ZEND_VM_C_GOTO ( num_index_prop ) ;
case IS_REFERENCE :
offset = Z_REFVAL_P ( offset ) ;
ZEND_VM_C_GOTO ( isset_again ) ;
default :
zend_error ( E_WARNING , " Illegal offset type in isset or empty " ) ;
value = NULL ;
break ;
}
2010-07-16 19:44:30 +08:00
}
if ( opline - > extended_value & ZEND_ISSET ) {
2014-04-07 18:56:34 +08:00
/* > IS_NULL means not IS_UNDEF and not IS_NULL */
result = ( value ! = NULL & & Z_TYPE_P ( value ) > IS_NULL ) ;
2010-07-16 19:44:30 +08:00
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
2014-04-07 18:56:34 +08:00
result = ( value = = NULL | | ! i_zend_is_true ( value TSRMLS_CC ) ) ;
2010-07-16 19:44:30 +08:00
}
2013-10-28 18:44:07 +08:00
} else if ( Z_TYPE_P ( container ) = = IS_OBJECT ) {
2014-04-22 04:32:29 +08:00
if ( Z_OBJ_HT_P ( container ) - > has_dimension ) {
result = Z_OBJ_HT_P ( container ) - > has_dimension ( container , offset , ( opline - > extended_value & ZEND_ISSET ) = = 0 TSRMLS_CC ) ;
2010-07-16 19:44:30 +08:00
} else {
2014-04-22 04:32:29 +08:00
zend_error ( E_NOTICE , " Trying to check element of non-array " ) ;
result = 0 ;
2010-07-16 19:44:30 +08:00
}
2014-04-07 18:56:34 +08:00
if ( ( opline - > extended_value & ZEND_ISSET ) = = 0 ) {
result = ! result ;
}
2014-04-22 04:32:29 +08:00
} else if ( Z_TYPE_P ( container ) = = IS_STRING ) { /* string offsets */
2010-07-16 19:44:30 +08:00
zval tmp ;
2014-04-07 18:56:34 +08:00
result = 0 ;
if ( UNEXPECTED ( Z_TYPE_P ( offset ) ! = IS_LONG ) ) {
2014-03-05 17:55:56 +08:00
if ( Z_TYPE_P ( offset ) < IS_STRING /* 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 ) ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_DUP ( & tmp , offset ) ;
2012-01-26 09:28:37 +08:00
convert_to_long ( & tmp ) ;
offset = & tmp ;
}
2010-07-16 19:44:30 +08:00
}
if ( Z_TYPE_P ( offset ) = = IS_LONG ) {
2014-04-07 18:56:34 +08:00
if ( offset - > value . lval > = 0 & & offset - > value . lval < Z_STRLEN_P ( container ) ) {
if ( ( opline - > extended_value & ZEND_ISSET ) | |
Z_STRVAL_P ( container ) [ offset - > value . lval ] ! = ' 0 ' ) {
2010-07-16 19:44:30 +08:00
result = 1 ;
2014-04-07 18:56:34 +08:00
}
2010-07-16 19:44:30 +08:00
}
}
2014-04-07 18:56:34 +08:00
if ( ( opline - > extended_value & ZEND_ISSET ) = = 0 ) {
result = ! result ;
}
2010-07-16 19:44:30 +08:00
} else {
2014-04-07 18:56:34 +08:00
result = ( ( opline - > extended_value & ZEND_ISSET ) = = 0 ) ;
2004-10-23 05:42:14 +08:00
}
2014-04-16 01:56:30 +08:00
FREE_OP2 ( ) ;
2014-04-07 18:56:34 +08:00
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , result ) ;
2013-10-28 19:23:10 +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 ( 148 , ZEND_ISSET_ISEMPTY_PROP_OBJ , VAR | UNUSED | CV , CONST | TMP | VAR | CV )
{
2014-04-22 04:32:29 +08:00
USE_OPLINE
zend_free_op free_op1 , free_op2 ;
zval * container ;
int result ;
zval * offset ;
SAVE_OPLINE ( ) ;
container = GET_OP1_OBJ_ZVAL_PTR_DEREF ( BP_VAR_IS ) ;
offset = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
if ( Z_TYPE_P ( container ) = = IS_OBJECT ) {
if ( Z_OBJ_HT_P ( container ) - > has_property ) {
result = Z_OBJ_HT_P ( container ) - > has_property ( container , offset , ( opline - > extended_value & ZEND_ISSET ) = = 0 , ( ( OP2_TYPE = = IS_CONST ) ? Z_CACHE_SLOT_P ( offset ) : - 1 ) TSRMLS_CC ) ;
} else {
zend_error ( E_NOTICE , " Trying to check property of non-object " ) ;
result = 0 ;
}
if ( ( opline - > extended_value & ZEND_ISSET ) = = 0 ) {
result = ! result ;
}
} else {
result = ( ( opline - > extended_value & ZEND_ISSET ) = = 0 ) ;
}
FREE_OP2 ( ) ;
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , result ) ;
FREE_OP1_IF_VAR ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2004-10-23 05:42:14 +08:00
}
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 {
2014-04-21 23:12:10 +08:00
zend_print_variable ( ptr TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
}
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 ( ) ;
2014-02-10 14:04:30 +08:00
ZVAL_LONG ( EX_VAR ( opline - > result . var ) , EG ( error_reporting ) ) ;
if ( Z_TYPE ( EX ( old_error_reporting ) ) = = IS_UNDEF ) {
ZVAL_LONG ( & EX ( old_error_reporting ) , EG ( error_reporting ) ) ;
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 ) ) {
2014-02-10 14:04:30 +08:00
zend_ini_entry * p = zend_hash_str_find_ptr ( EG ( ini_directives ) , " error_reporting " , sizeof ( " error_reporting " ) - 1 ) ;
if ( p ) {
EG ( error_reporting_ini_entry ) = p ;
} else {
2010-08-18 21:58:13 +08:00
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 ) ;
}
2014-02-10 14:04:30 +08:00
if ( EXPECTED ( zend_hash_str_add_ptr ( EG ( modified_ini_directives ) , " error_reporting " , sizeof ( " error_reporting " ) - 1 , EG ( error_reporting_ini_entry ) ) ! = NULL ) ) {
2010-08-18 21:58:13 +08:00
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 ( ) ;
2014-07-04 21:03:44 +08:00
zend_error_noreturn ( E_ERROR , " Cannot call abstract method %s::%s() " , EX ( scope ) - > name - > val , EX ( func ) - > op_array . function_name - > val ) ;
2004-10-23 05:42:14 +08:00
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
2014-06-09 21:36:37 +08:00
char buf [ MAX_LENGTH_OF_LONG + 1 ] ;
char * res ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-02-10 14:04:30 +08:00
if ( ! EG ( error_reporting ) & & Z_LVAL_P ( EX_VAR ( opline - > op1 . var ) ) ! = 0 ) {
2014-06-09 21:36:37 +08:00
EG ( error_reporting ) = Z_LVAL_P ( EX_VAR ( opline - > op1 . var ) ) ;
_zend_print_signed_to_buf ( buf + sizeof ( buf ) - 1 , EG ( error_reporting ) , unsigned long , res ) ;
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 ) ;
}
2014-06-09 21:36:37 +08:00
EG ( error_reporting_ini_entry ) - > value_length = buf + sizeof ( buf ) - 1 - res ;
EG ( error_reporting_ini_entry ) - > value = estrndup ( res , EG ( error_reporting_ini_entry ) - > value_length ) ;
2014-02-19 18:41:50 +08:00
}
2004-10-23 05:42:14 +08:00
}
2014-02-10 14:04:30 +08:00
//??? if (EX(old_error_reporting) == EX_VAR(opline->op1.var)) {
//??? 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
2013-12-18 14:25:05 +08:00
if ( i_zend_is_true ( value TSRMLS_CC ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_COPY_VALUE ( EX_VAR ( opline - > result . var ) , value ) ;
2014-06-05 20:04:11 +08:00
if ( OP1_TYPE = = IS_CONST ) {
if ( UNEXPECTED ( Z_OPT_COPYABLE_P ( value ) ) ) {
zval_copy_ctor_func ( EX_VAR ( opline - > result . var ) ) ;
}
} else if ( OP1_TYPE = = IS_CV ) {
if ( Z_OPT_REFCOUNTED_P ( value ) ) Z_ADDREF_P ( value ) ;
2011-10-19 03:42:42 +08:00
}
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 ;
2014-02-10 14:04:30 +08:00
zval * value ;
2011-10-19 03:42:42 +08:00
SAVE_OPLINE ( ) ;
value = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2013-12-18 14:25:05 +08:00
if ( i_zend_is_true ( value TSRMLS_CC ) ) {
2014-06-05 20:04:11 +08:00
ZVAL_COPY_VALUE ( EX_VAR ( opline - > result . var ) , value ) ;
if ( OP1_TYPE = = IS_CONST ) {
if ( UNEXPECTED ( Z_OPT_COPYABLE_P ( value ) ) ) {
zval_copy_ctor_func ( EX_VAR ( opline - > result . var ) ) ;
2011-10-19 03:42:42 +08:00
}
2014-06-05 20:04:11 +08:00
} else if ( OP1_TYPE = = IS_CV ) {
if ( Z_OPT_REFCOUNTED_P ( value ) ) Z_ADDREF_P ( value ) ;
2011-10-19 03:42:42 +08:00
}
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 ) ;
2014-02-10 14:04:30 +08:00
ZVAL_COPY_VALUE ( EX_VAR ( opline - > result . var ) , value ) ;
2014-06-05 20:04:11 +08:00
if ( OP1_TYPE = = IS_CONST ) {
if ( UNEXPECTED ( Z_OPT_COPYABLE_P ( value ) ) ) {
zval_copy_ctor_func ( EX_VAR ( opline - > result . var ) ) ;
}
} else if ( OP1_TYPE = = IS_CV ) {
if ( Z_OPT_REFCOUNTED_P ( value ) ) Z_ADDREF_P ( value ) ;
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 ;
2014-02-10 14:04:30 +08:00
zval * value ;
2011-10-19 03:42:42 +08:00
SAVE_OPLINE ( ) ;
value = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-06-05 20:04:11 +08:00
ZVAL_COPY_VALUE ( EX_VAR ( opline - > result . var ) , value ) ;
if ( OP1_TYPE = = IS_CONST ) {
if ( UNEXPECTED ( Z_OPT_COPYABLE_P ( value ) ) ) {
zval_copy_ctor_func ( EX_VAR ( opline - > result . var ) ) ;
2011-10-19 03:42:42 +08:00
}
2014-06-05 20:04:11 +08:00
} else if ( OP1_TYPE = = IS_CV ) {
if ( Z_OPT_REFCOUNTED_P ( value ) ) Z_ADDREF_P ( value ) ;
2011-10-19 03:42:42 +08:00
}
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 ) ) {
2014-06-30 19:43:45 +08:00
zend_llist_apply_with_argument ( & zend_extensions , ( llist_apply_with_arg_func_t ) zend_extension_statement_handler , EX ( func ) 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 ( ) ;
}
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 ) ) {
2014-06-30 19:43:45 +08:00
zend_llist_apply_with_argument ( & zend_extensions , ( llist_apply_with_arg_func_t ) zend_extension_fcall_begin_handler , EX ( func ) 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 ( ) ;
}
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 ) ) {
2014-06-30 19:43:45 +08:00
zend_llist_apply_with_argument ( & zend_extensions , ( llist_apply_with_arg_func_t ) zend_extension_fcall_end_handler , EX ( func ) 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 ( ) ;
}
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 ( ) ;
2014-06-30 19:43:45 +08:00
Z_CE_P ( EX_VAR ( opline - > result . var ) ) = do_bind_class ( & EX ( func ) - > 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 ( ) ;
2014-06-30 19:43:45 +08:00
Z_CE_P ( EX_VAR ( opline - > result . var ) ) = do_bind_inherited_class ( & EX ( func ) - > op_array , opline , EG ( class_table ) , Z_CE_P ( EX_VAR ( opline - > extended_value ) ) , 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
2014-02-10 14:04:30 +08:00
zval * zce , * orig_zce ;
2008-03-18 16:36:30 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-02-10 14:04:30 +08:00
if ( ( zce = zend_hash_find ( EG ( class_table ) , Z_STR_P ( opline - > op2 . zv ) ) ) = = NULL | |
( ( orig_zce = zend_hash_find ( EG ( class_table ) , Z_STR_P ( opline - > op1 . zv ) ) ) ! = NULL & &
Z_CE_P ( zce ) ! = Z_CE_P ( orig_zce ) ) ) {
2014-06-30 19:43:45 +08:00
do_bind_inherited_class ( & EX ( func ) - > op_array , opline , EG ( class_table ) , Z_CE_P ( EX_VAR ( opline - > extended_value ) ) , 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 ( ) ;
2014-07-05 20:12:20 +08:00
do_bind_function ( & EX ( func ) - > op_array , opline , EG ( function_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 ( ) ;
}
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 ) {
2013-12-18 16:32:26 +08:00
zend_ticks_function ( opline - > extended_value 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 ( ) ;
}
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 ( ) ;
2014-03-27 17:39:09 +08:00
expr = GET_OP1_ZVAL_PTR_DEREF ( 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 ) {
2014-02-10 14:04:30 +08:00
result = instanceof_function ( Z_OBJCE_P ( expr ) , Z_CE_P ( EX_VAR ( opline - > op2 . var ) ) TSRMLS_CC ) ;
2004-10-23 05:42:14 +08:00
} else {
result = 0 ;
}
2014-02-10 14:04:30 +08:00
ZVAL_BOOL ( EX_VAR ( opline - > result . 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
2014-02-10 14:04:30 +08:00
zend_class_entry * ce = Z_CE_P ( EX_VAR ( opline - > op1 . var ) ) ;
2010-04-20 19:16:39 +08:00
zend_class_entry * iface ;
SAVE_OPLINE ( ) ;
2014-04-17 19:40:45 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ) {
iface = CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-04-17 19:40:45 +08:00
iface = zend_fetch_class_by_name ( Z_STR_P ( opline - > op2 . zv ) , opline - > op2 . zv + 1 , opline - > extended_value TSRMLS_CC ) ;
2010-05-24 22:11:39 +08:00
if ( UNEXPECTED ( iface = = NULL ) ) {
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2009-11-02 05:26:03 +08:00
}
2014-04-17 19:40:45 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) , iface ) ;
2010-05-24 22:11:39 +08:00
}
if ( UNEXPECTED ( ( iface - > ce_flags & ZEND_ACC_INTERFACE ) = = 0 ) ) {
2014-02-22 00:44:26 +08:00
zend_error_noreturn ( E_ERROR , " %s cannot implement %s - it is not an interface " , ce - > name - > val , iface - > name - > val ) ;
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
2014-02-10 14:04:30 +08:00
zend_class_entry * ce = Z_CE_P ( EX_VAR ( opline - > op1 . var ) ) ;
2010-05-24 22:11:39 +08:00
zend_class_entry * trait ;
2011-05-06 00:02:11 +08:00
SAVE_OPLINE ( ) ;
2014-04-17 19:40:45 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ) {
trait = CACHED_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-02-10 14:04:30 +08:00
trait = zend_fetch_class_by_name ( Z_STR_P ( opline - > op2 . zv ) ,
2014-04-17 19:40:45 +08:00
opline - > op2 . zv + 1 ,
2010-05-24 22:11:39 +08:00
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 ) ) {
2014-02-22 00:44:26 +08:00
zend_error_noreturn ( E_ERROR , " %s cannot use %s - it is not a trait " , ce - > name - > val , trait - > name - > val ) ;
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
}
2014-04-17 19:40:45 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( opline - > op2 . zv ) , 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
2014-02-10 14:04:30 +08:00
zend_class_entry * ce = Z_CE_P ( EX_VAR ( opline - > op1 . var ) ) ;
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 )
{
2014-06-30 19:43:45 +08:00
zend_uint op_num = EG ( opline_before_exception ) - EX ( func ) - > op_array . opcodes ;
2004-10-23 05:42:14 +08:00
int i ;
2013-12-13 00:15:50 +08:00
zend_uint catch_op_num = 0 , finally_op_num = 0 , finally_op_end = 0 ;
2008-01-24 17:41:39 +08:00
2014-06-30 19:43:45 +08:00
for ( i = 0 ; i < EX ( func ) - > op_array . last_try_catch ; i + + ) {
if ( EX ( func ) - > op_array . try_catch_array [ i ] . try_op > op_num ) {
2004-10-23 05:42:14 +08:00
/* further blocks will not be relevant... */
break ;
2012-10-05 14:14:20 +08:00
}
2014-06-30 19:43:45 +08:00
if ( op_num < EX ( func ) - > op_array . try_catch_array [ i ] . catch_op ) {
catch_op_num = EX ( func ) - > op_array . try_catch_array [ i ] . catch_op ;
2004-10-23 05:42:14 +08:00
}
2014-06-30 19:43:45 +08:00
if ( op_num < EX ( func ) - > op_array . try_catch_array [ i ] . finally_op ) {
finally_op_num = EX ( func ) - > op_array . try_catch_array [ i ] . finally_op ;
2012-08-14 08:59:40 +08:00
}
2014-06-30 19:43:45 +08:00
if ( op_num > = EX ( func ) - > op_array . try_catch_array [ i ] . finally_op & &
op_num < EX ( func ) - > op_array . try_catch_array [ i ] . finally_end ) {
finally_op_end = EX ( func ) - > op_array . try_catch_array [ i ] . finally_end ;
2013-12-13 00:15:50 +08:00
}
2004-10-23 05:42:14 +08:00
}
2014-06-30 19:43:45 +08:00
if ( EX ( call ) ) {
zend_execute_data * call = EX ( call ) ;
2012-11-30 17:39:23 +08:00
do {
2014-06-30 19:43:45 +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 . */
zend_vm_stack_free_args ( EX ( call ) TSRMLS_CC ) ;
2014-03-28 06:11:22 +08:00
if ( call - > object ) {
2014-06-30 19:43:45 +08:00
if ( call - > flags & ZEND_CALL_CTOR ) {
if ( ! ( call - > flags & ZEND_CALL_CTOR_RESULT_UNUSED ) ) {
2014-04-02 18:34:44 +08:00
GC_REFCOUNT ( call - > object ) - - ;
2012-11-30 17:39:23 +08:00
}
2014-04-02 18:34:44 +08:00
if ( GC_REFCOUNT ( call - > object ) = = 1 ) {
2014-03-28 06:11:22 +08:00
zend_object_store_ctor_failed ( call - > object TSRMLS_CC ) ;
2012-11-30 17:39:23 +08:00
}
2009-03-26 18:17:30 +08:00
}
2014-03-28 06:11:22 +08:00
OBJ_RELEASE ( call - > object ) ;
2005-10-20 15:23:26 +08:00
}
2014-06-30 19:43:45 +08:00
EX ( call ) = call - > prev_nested_call ;
zend_vm_stack_free_call_frame ( call TSRMLS_CC ) ;
call = EX ( call ) ;
} while ( call ) ;
2005-05-04 19:17:30 +08:00
}
2014-06-30 19:43:45 +08:00
for ( i = 0 ; i < EX ( func ) - > op_array . last_brk_cont ; i + + ) {
if ( EX ( func ) - > op_array . brk_cont_array [ i ] . start < 0 ) {
2008-02-20 20:05:57 +08:00
continue ;
2014-06-30 19:43:45 +08:00
} else if ( EX ( func ) - > op_array . brk_cont_array [ i ] . start > op_num ) {
2006-09-20 05:36:54 +08:00
/* further blocks will not be relevant... */
break ;
2014-06-30 19:43:45 +08:00
} else if ( op_num < EX ( func ) - > op_array . brk_cont_array [ i ] . brk ) {
2012-11-22 19:17:05 +08:00
if ( ! catch_op_num | |
2014-06-30 19:43:45 +08:00
catch_op_num > = EX ( func ) - > op_array . brk_cont_array [ i ] . brk ) {
zend_op * brk_opline = & EX ( func ) - > op_array . opcodes [ EX ( func ) - > op_array . brk_cont_array [ i ] . brk ] ;
2006-09-20 05:36:54 +08:00
2014-06-05 22:42:17 +08:00
if ( brk_opline - > opcode = = ZEND_SWITCH_FREE ) {
if ( ! ( brk_opline - > extended_value & EXT_TYPE_FREE_ON_RETURN ) ) {
zval_ptr_dtor ( EX_VAR ( brk_opline - > op1 . var ) ) ;
}
} else if ( brk_opline - > opcode = = ZEND_FREE ) {
if ( ! ( brk_opline - > extended_value & EXT_TYPE_FREE_ON_RETURN ) ) {
zval_dtor ( EX_VAR ( brk_opline - > op1 . var ) ) ;
}
2006-09-20 05:36:54 +08:00
}
}
}
}
2005-09-23 03:03:18 +08:00
/* restore previous error_reporting value */
2014-02-10 14:04:30 +08:00
if ( ! EG ( error_reporting ) & & Z_TYPE ( EX ( old_error_reporting ) ) ! = IS_UNDEF & & Z_LVAL ( EX ( old_error_reporting ) ) ! = 0 ) {
2012-05-30 22:28:33 +08:00
zval restored_error_reporting ;
2014-02-10 14:04:30 +08:00
zend_string * key ;
2012-05-30 22:28:33 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_LONG ( & restored_error_reporting , Z_LVAL ( EX ( old_error_reporting ) ) ) ;
2005-09-23 03:03:18 +08:00
convert_to_string ( & restored_error_reporting ) ;
2014-02-10 14:04:30 +08:00
key = STR_INIT ( " error_reporting " , sizeof ( " error_reporting " ) - 1 , 0 ) ;
zend_alter_ini_entry_ex ( key , Z_STRVAL ( restored_error_reporting ) , Z_STRLEN ( restored_error_reporting ) , ZEND_INI_USER , ZEND_INI_STAGE_RUNTIME , 1 TSRMLS_CC ) ;
STR_FREE ( key ) ;
zval_dtor ( & restored_error_reporting ) ;
2005-09-23 03:03:18 +08:00
}
2014-02-10 14:04:30 +08:00
ZVAL_UNDEF ( & EX ( old_error_reporting ) ) ;
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 ) ) {
2013-12-13 00:15:50 +08:00
if ( EX ( delayed_exception ) ) {
zend_exception_set_previous ( EG ( exception ) , EX ( delayed_exception ) TSRMLS_CC ) ;
}
EX ( delayed_exception ) = EG ( exception ) ;
EG ( exception ) = NULL ;
2012-11-22 19:17:05 +08:00
EX ( fast_ret ) = NULL ;
2014-06-30 19:43:45 +08:00
ZEND_VM_SET_OPCODE ( & EX ( func ) - > op_array . opcodes [ finally_op_num ] ) ;
2012-08-14 08:59:40 +08:00
ZEND_VM_CONTINUE ( ) ;
2012-11-22 19:17:05 +08:00
} else if ( catch_op_num ) {
2013-12-13 00:15:50 +08:00
if ( finally_op_end & & catch_op_num > finally_op_end ) {
/* we are going out of current finally scope */
if ( EX ( delayed_exception ) ) {
zend_exception_set_previous ( EG ( exception ) , EX ( delayed_exception ) TSRMLS_CC ) ;
EX ( delayed_exception ) = NULL ;
}
}
2014-06-30 19:43:45 +08:00
ZEND_VM_SET_OPCODE ( & EX ( func ) - > op_array . opcodes [ catch_op_num ] ) ;
2012-11-22 19:17:05 +08:00
ZEND_VM_CONTINUE ( ) ;
2012-08-14 08:59:40 +08:00
} else {
2013-12-13 00:15:50 +08:00
if ( EX ( delayed_exception ) ) {
zend_exception_set_previous ( EG ( exception ) , EX ( delayed_exception ) TSRMLS_CC ) ;
EX ( delayed_exception ) = NULL ;
}
2014-06-30 19:43:45 +08:00
if ( UNEXPECTED ( ( EX ( func ) - > op_array . fn_flags & ZEND_ACC_GENERATOR ) ! = 0 ) ) {
2012-12-11 21:25:32 +08:00
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 ( ) ;
2014-02-10 14:04:30 +08:00
zend_verify_abstract_class ( Z_CE_P ( EX_VAR ( opline - > op1 . var ) ) TSRMLS_CC ) ;
2010-04-20 19:16:39 +08:00
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 :
2014-06-30 19:43:45 +08:00
if ( UNEXPECTED ( ( EX ( func ) - > op_array . fn_flags & ZEND_ACC_GENERATOR ) ! = 0 ) ) {
2012-12-11 21:25:32 +08:00
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 ) ;
2014-04-04 07:55:27 +08:00
ZVAL_COPY_VALUE ( & c . value , val ) ;
if ( Z_OPT_CONSTANT ( c . value ) ) {
2014-04-26 04:32:51 +08:00
zval_update_constant ( & c . value , 0 TSRMLS_CC ) ;
2007-09-29 03:52:53 +08:00
} else {
2014-04-04 07:55:27 +08:00
/* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
if ( UNEXPECTED ( Z_OPT_COPYABLE ( c . value ) ) ) {
2014-06-05 20:04:11 +08:00
zval_copy_ctor_func ( & c . value ) ;
2014-04-04 07:55:27 +08:00
}
2007-09-29 03:52:53 +08:00
}
c . flags = CONST_CS ; /* non persistent, case sensetive */
2014-02-10 14:04:30 +08:00
c . name = STR_DUP ( Z_STR_P ( name ) , 0 ) ;
2007-09-29 03:52:53 +08:00
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
2014-02-10 14:04:30 +08:00
zval * zfunc ;
2014-05-13 11:53:08 +08:00
int closure_is_static , closure_is_being_defined_inside_static_context ;
2008-07-14 17:49:03 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-02-10 14:04:30 +08:00
if ( UNEXPECTED ( ( zfunc = zend_hash_find ( EG ( function_table ) , Z_STR_P ( opline - > op1 . zv ) ) ) = = NULL ) | |
UNEXPECTED ( Z_FUNC_P ( zfunc ) - > type ! = ZEND_USER_FUNCTION ) ) {
2008-07-14 17:49:03 +08:00
zend_error_noreturn ( E_ERROR , " Base lambda function for closure not found " ) ;
}
2014-06-12 09:07:33 +08:00
closure_is_static = Z_FUNC_P ( zfunc ) - > common . fn_flags & ZEND_ACC_STATIC ;
2014-07-07 19:50:44 +08:00
closure_is_being_defined_inside_static_context = EX ( func ) - > common . fn_flags & ZEND_ACC_STATIC ;
2014-05-13 11:53:08 +08:00
if ( closure_is_static | | closure_is_being_defined_inside_static_context ) {
2014-07-03 06:34:43 +08:00
zend_create_closure ( EX_VAR ( opline - > result . var ) , Z_FUNC_P ( zfunc ) , EX ( called_scope ) , NULL TSRMLS_CC ) ;
2014-05-13 11:53:08 +08:00
} else {
2014-07-04 21:03:44 +08:00
zend_create_closure ( EX_VAR ( opline - > result . var ) , Z_FUNC_P ( zfunc ) , EX ( scope ) , Z_OBJ ( EG ( This ) ) ? & EG ( This ) : NULL TSRMLS_CC ) ;
2014-05-13 11:53:08 +08:00
}
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
2014-02-10 14:04:30 +08:00
zval * var_ptr ;
2010-08-25 17:14:36 +08:00
SAVE_OPLINE ( ) ;
2014-02-10 14:04:30 +08:00
var_ptr = EX_VAR ( opline - > op1 . var ) ;
2014-03-04 16:27:50 +08:00
if ( Z_TYPE_P ( var_ptr ) ! = IS_OBJECT & &
! Z_ISREF_P ( var_ptr ) & &
Z_REFCOUNTED_P ( var_ptr ) & &
Z_REFCOUNT_P ( var_ptr ) > 1 ) {
Z_DELREF_P ( var_ptr ) ;
2014-02-10 14:04:30 +08:00
ZVAL_DUP ( EX_VAR ( opline - > op1 . var ) , var_ptr ) ;
2010-08-25 17:14:36 +08:00
}
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
2014-02-26 17:58:59 +08:00
/* The generator object is stored in EX(return_value) */
zend_generator * generator = ( zend_generator * ) EX ( return_value ) ;
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 */
2014-02-12 18:29:51 +08:00
zval_ptr_dtor ( & generator - > value ) ;
2012-05-27 04:44:53 +08:00
2012-05-30 08:44:06 +08:00
/* Destroy the previously yielded key */
2014-02-12 18:29:51 +08:00
zval_ptr_dtor ( & generator - > key ) ;
2012-05-30 08:44:06 +08:00
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 ;
2014-06-30 19:43:45 +08:00
if ( EX ( func ) - > op_array . fn_flags & ZEND_ACC_RETURN_REFERENCE ) {
2012-07-17 19:24:27 +08:00
/* 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 ) {
2014-02-12 18:29:51 +08:00
zval * value ;
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 ) ;
2014-02-12 18:29:51 +08:00
ZVAL_COPY_VALUE ( & generator - > value , value ) ;
2014-04-04 06:52:53 +08:00
if ( Z_OPT_REFCOUNTED ( generator - > value ) ) Z_SET_REFCOUNT ( generator - > value , 1 ) ;
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 ( ) ) {
2014-02-12 18:29:51 +08:00
zval_copy_ctor ( & generator - > value ) ;
2012-07-17 19:24:27 +08:00
}
} else {
2014-03-04 16:27:50 +08:00
zval * value_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_W ) ;
2012-05-27 04:44:53 +08:00
2014-02-12 18:29:51 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( Z_TYPE_P ( value_ptr ) = = IS_STR_OFFSET ) ) {
2012-07-17 19:24:27 +08:00
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 . */
2014-02-12 18:29:51 +08:00
if ( OP1_TYPE = = IS_VAR & & ! Z_ISREF_P ( value_ptr )
2014-03-07 16:25:55 +08:00
& & ! ( opline - > extended_value = = ZEND_RETURNS_FUNCTION
2014-04-16 05:45:40 +08:00
& & ( Z_VAR_FLAGS_P ( value_ptr ) & IS_VAR_RET_REF ) ) ) {
2012-07-17 19:24:27 +08:00
zend_error ( E_NOTICE , " Only variable references should be yielded by reference " ) ;
} else {
2014-06-05 20:04:11 +08:00
ZVAL_MAKE_REF ( value_ptr ) ;
2012-07-17 19:24:27 +08:00
}
2014-02-12 18:29:51 +08:00
ZVAL_COPY ( & generator - > value , value_ptr ) ;
2012-07-17 19:24:27 +08:00
2013-05-17 17:15:09 +08:00
FREE_OP1_VAR_PTR ( ) ;
2012-07-17 19:24:27 +08:00
}
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 */
2014-04-16 05:45:40 +08:00
if ( OP1_TYPE = = IS_CONST ) {
ZVAL_DUP ( & generator - > value , value ) ;
} else if ( OP1_TYPE = = IS_TMP_VAR ) {
2014-02-12 18:29:51 +08:00
ZVAL_COPY_VALUE ( & generator - > value , value ) ;
2014-04-16 05:45:40 +08:00
} else if ( Z_ISREF_P ( value ) ) {
ZVAL_DUP ( & generator - > value , Z_REFVAL_P ( value ) ) ;
2013-05-17 17:15:09 +08:00
FREE_OP1_IF_VAR ( ) ;
2012-07-17 19:24:27 +08:00
} else {
2013-05-17 17:15:09 +08:00
if ( OP1_TYPE = = IS_CV ) {
2014-02-26 17:58:59 +08:00
if ( Z_REFCOUNTED_P ( value ) ) Z_ADDREF_P ( value ) ;
2013-05-17 17:15:09 +08:00
}
2014-02-12 18:29:51 +08:00
ZVAL_COPY_VALUE ( & generator - > value , value ) ;
2012-07-17 19:24:27 +08:00
}
}
2012-05-29 23:53:11 +08:00
} else {
2012-05-30 08:44:06 +08:00
/* If no value was specified yield null */
2014-02-12 18:29:51 +08:00
ZVAL_NULL ( & generator - > value ) ;
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 */
2014-04-16 05:45:40 +08:00
if ( OP2_TYPE = = IS_CONST ) {
ZVAL_DUP ( & generator - > key , key ) ;
} else if ( OP2_TYPE = = IS_TMP_VAR ) {
2014-02-12 18:29:51 +08:00
ZVAL_COPY_VALUE ( & generator - > key , key ) ;
2014-04-16 05:45:40 +08:00
} else if ( Z_ISREF_P ( key ) ) {
ZVAL_DUP ( & generator - > key , Z_REFVAL_P ( key ) ) ;
FREE_OP2_IF_VAR ( ) ;
2012-05-30 08:44:06 +08:00
} else {
2014-04-16 20:35:41 +08:00
if ( OP2_TYPE = = IS_CV ) {
2014-04-16 05:45:40 +08:00
if ( Z_REFCOUNTED_P ( key ) ) Z_ADDREF_P ( key ) ;
}
ZVAL_COPY_VALUE ( & generator - > key , key ) ;
2012-05-30 08:44:06 +08:00
}
2014-02-12 18:29:51 +08:00
if ( Z_TYPE ( generator - > key ) = = IS_LONG
& & Z_LVAL ( generator - > key ) > generator - > largest_used_integer_key
2012-05-30 11:05:49 +08:00
) {
2014-02-12 18:29:51 +08:00
generator - > largest_used_integer_key = Z_LVAL ( generator - > key ) ;
2012-05-30 11:05:49 +08:00
}
2012-05-30 08:44:06 +08:00
} else {
2012-05-30 11:05:49 +08:00
/* If no key was specified we use auto-increment keys */
generator - > largest_used_integer_key + + ;
2014-02-12 18:29:51 +08:00
ZVAL_LONG ( & generator - > key , generator - > largest_used_integer_key ) ;
2012-05-30 08:44:06 +08:00
}
2013-11-30 20:05:40 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
/* If the return value of yield is used set the send
* target and initialize it to NULL */
2014-02-12 18:29:51 +08:00
generator - > send_target = EX_VAR ( opline - > result . var ) ;
ZVAL_NULL ( generator - > send_target ) ;
2013-11-30 20:05:40 +08:00
} else {
generator - > send_target = NULL ;
}
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 )
{
2013-12-13 00:15:50 +08:00
if ( EX ( delayed_exception ) ! = NULL ) {
2012-12-13 06:48:51 +08:00
/* discard the previously thrown exception */
2014-03-22 01:48:38 +08:00
OBJ_RELEASE ( EX ( delayed_exception ) ) ;
2013-12-13 00:15:50 +08:00
EX ( delayed_exception ) = NULL ;
2012-12-13 06:48:51 +08:00
}
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 & &
2013-02-19 12:56:02 +08:00
UNEXPECTED ( EG ( prev_exception ) ! = NULL ) ) {
2012-11-22 19:17:05 +08:00
/* in case of unhandled exception jump to catch block instead of finally */
2014-06-30 19:43:45 +08:00
ZEND_VM_SET_OPCODE ( & EX ( func ) - > op_array . opcodes [ opline - > op2 . opline_num ] ) ;
2012-11-22 19:17:05 +08:00
ZEND_VM_CONTINUE ( ) ;
}
EX ( fast_ret ) = opline + 1 ;
2013-12-13 00:15:50 +08:00
EX ( delayed_exception ) = NULL ;
2012-11-22 19:17:05 +08:00
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 ) {
2014-06-30 19:43:45 +08:00
ZEND_VM_SET_OPCODE ( & EX ( func ) - > op_array . opcodes [ opline - > op2 . opline_num ] ) ;
2012-11-22 19:17:05 +08:00
ZEND_VM_CONTINUE ( ) ;
} else {
2013-12-13 00:15:50 +08:00
EG ( exception ) = EX ( delayed_exception ) ;
EX ( delayed_exception ) = NULL ;
if ( opline - > extended_value = = ZEND_FAST_RET_TO_CATCH ) {
2014-06-30 19:43:45 +08:00
ZEND_VM_SET_OPCODE ( & EX ( func ) - > op_array . opcodes [ opline - > op2 . opline_num ] ) ;
2013-12-13 00:15:50 +08:00
ZEND_VM_CONTINUE ( ) ;
2014-06-30 19:43:45 +08:00
} else if ( UNEXPECTED ( ( EX ( func ) - > op_array . fn_flags & ZEND_ACC_GENERATOR ) ! = 0 ) ) {
2013-12-13 00:15:50 +08:00
ZEND_VM_DISPATCH_TO_HANDLER ( ZEND_GENERATOR_RETURN ) ;
} else {
ZEND_VM_DISPATCH_TO_HELPER ( zend_leave_helper ) ;
}
2012-11-22 19:17:05 +08:00
}
}
}
2013-11-19 15:36:06 +08:00
ZEND_VM_HANDLER ( 166 , ZEND_POW , CONST | TMP | VAR | CV , CONST | TMP | VAR | CV )
{
USE_OPLINE
zend_free_op free_op1 , free_op2 ;
SAVE_OPLINE ( ) ;
2014-04-26 04:32:51 +08:00
pow_function ( EX_VAR ( opline - > result . var ) ,
GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR_DEREF ( BP_VAR_R ) TSRMLS_CC ) ;
2013-11-19 15:36:06 +08:00
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 167 , ZEND_ASSIGN_POW , VAR | UNUSED | CV , CONST | TMP | VAR | UNUSED | CV )
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , pow_function ) ;
}
2014-06-06 19:04:30 +08:00
ZEND_VM_HANDLER ( 168 , ZEND_BIND_GLOBAL , CV , CONST )
{
USE_OPLINE
zend_free_op free_op1 , free_op2 ;
zval * varname ;
zval * value ;
zval * variable_ptr ;
zend_string * name ;
SAVE_OPLINE ( ) ;
varname = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
name = Z_STR_P ( varname ) ;
value = zend_hash_find ( & EG ( symbol_table ) . ht , name ) ;
if ( value = = NULL ) {
value = zend_hash_add_new ( & EG ( symbol_table ) . ht , name , & EG ( uninitialized_zval ) ) ;
/* GLOBAL variable may be an INDIRECT pointer to CV */
} else if ( Z_TYPE_P ( value ) = = IS_INDIRECT ) {
value = Z_INDIRECT_P ( value ) ;
if ( Z_TYPE_P ( value ) = = IS_UNDEF ) {
ZVAL_NULL ( value ) ;
}
}
variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF ( BP_VAR_W ) ;
zend_assign_to_variable_reference ( variable_ptr , value TSRMLS_CC ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-06-30 19:43:45 +08:00
ZEND_VM_EXPORT_HANDLER ( zend_do_fcall , ZEND_DO_FCALL )