2005-01-10 22:57:36 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Zend Engine |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2015-01-15 23:27:30 +08:00
| Copyright ( c ) 1998 - 2015 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
*/
2014-12-03 23:02:02 +08:00
ZEND_VM_HANDLER ( 1 , ZEND_ADD , CONST | TMPVAR | CV , CONST | TMPVAR | 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 ;
2015-03-17 23:53:19 +08:00
zval * op1 , * op2 , * result ;
op1 = GET_OP1_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
op2 = GET_OP2_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_LONG ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_LONG ) ) {
result = EX_VAR ( opline - > result . var ) ;
fast_long_add_function ( result , op1 , op2 ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_DOUBLE ) ) {
result = EX_VAR ( opline - > result . var ) ;
ZVAL_DOUBLE ( result , ( ( double ) Z_LVAL_P ( op1 ) ) + Z_DVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
} else if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_DOUBLE ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_DOUBLE ) ) {
result = EX_VAR ( opline - > result . var ) ;
ZVAL_DOUBLE ( result , Z_DVAL_P ( op1 ) + Z_DVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_LONG ) ) {
result = EX_VAR ( opline - > result . var ) ;
ZVAL_DOUBLE ( result , Z_DVAL_P ( op1 ) + ( ( double ) Z_LVAL_P ( op2 ) ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
}
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2015-03-17 23:53:19 +08:00
if ( OP1_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op1 ) = = IS_UNDEF ) ) {
op1 = GET_OP1_UNDEF_CV ( op1 , BP_VAR_R ) ;
}
if ( OP2_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op2 ) = = IS_UNDEF ) ) {
op2 = GET_OP2_UNDEF_CV ( op2 , BP_VAR_R ) ;
}
add_function ( EX_VAR ( opline - > result . var ) , op1 , op2 ) ;
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 ( ) ;
}
2014-12-03 23:02:02 +08:00
ZEND_VM_HANDLER ( 2 , ZEND_SUB , CONST | TMPVAR | CV , CONST | TMPVAR | 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 ;
2015-03-17 23:53:19 +08:00
zval * op1 , * op2 , * result ;
op1 = GET_OP1_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
op2 = GET_OP2_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_LONG ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_LONG ) ) {
result = EX_VAR ( opline - > result . var ) ;
fast_long_sub_function ( result , op1 , op2 ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_DOUBLE ) ) {
result = EX_VAR ( opline - > result . var ) ;
ZVAL_DOUBLE ( result , ( ( double ) Z_LVAL_P ( op1 ) ) - Z_DVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
} else if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_DOUBLE ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_DOUBLE ) ) {
result = EX_VAR ( opline - > result . var ) ;
ZVAL_DOUBLE ( result , Z_DVAL_P ( op1 ) - Z_DVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_LONG ) ) {
result = EX_VAR ( opline - > result . var ) ;
ZVAL_DOUBLE ( result , Z_DVAL_P ( op1 ) - ( ( double ) Z_LVAL_P ( op2 ) ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
}
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2015-03-17 23:53:19 +08:00
if ( OP1_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op1 ) = = IS_UNDEF ) ) {
op1 = GET_OP1_UNDEF_CV ( op1 , BP_VAR_R ) ;
}
if ( OP2_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op2 ) = = IS_UNDEF ) ) {
op2 = GET_OP2_UNDEF_CV ( op2 , BP_VAR_R ) ;
}
sub_function ( EX_VAR ( opline - > result . var ) , op1 , op2 ) ;
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 ( ) ;
}
2014-12-03 23:02:02 +08:00
ZEND_VM_HANDLER ( 3 , ZEND_MUL , CONST | TMPVAR | CV , CONST | TMPVAR | 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 ;
2015-03-17 23:53:19 +08:00
zval * op1 , * op2 , * result ;
op1 = GET_OP1_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
op2 = GET_OP2_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_LONG ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_LONG ) ) {
zend_long overflow ;
result = EX_VAR ( opline - > result . var ) ;
ZEND_SIGNED_MULTIPLY_LONG ( Z_LVAL_P ( op1 ) , Z_LVAL_P ( op2 ) , Z_LVAL_P ( result ) , Z_DVAL_P ( result ) , overflow ) ;
Z_TYPE_INFO_P ( result ) = overflow ? IS_DOUBLE : IS_LONG ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_DOUBLE ) ) {
result = EX_VAR ( opline - > result . var ) ;
ZVAL_DOUBLE ( result , ( ( double ) Z_LVAL_P ( op1 ) ) * Z_DVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
} else if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_DOUBLE ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_DOUBLE ) ) {
result = EX_VAR ( opline - > result . var ) ;
ZVAL_DOUBLE ( result , Z_DVAL_P ( op1 ) * Z_DVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_LONG ) ) {
result = EX_VAR ( opline - > result . var ) ;
ZVAL_DOUBLE ( result , Z_DVAL_P ( op1 ) * ( ( double ) Z_LVAL_P ( op2 ) ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
}
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2015-03-17 23:53:19 +08:00
if ( OP1_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op1 ) = = IS_UNDEF ) ) {
op1 = GET_OP1_UNDEF_CV ( op1 , BP_VAR_R ) ;
}
if ( OP2_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op2 ) = = IS_UNDEF ) ) {
op2 = GET_OP2_UNDEF_CV ( op2 , BP_VAR_R ) ;
}
mul_function ( EX_VAR ( opline - > result . var ) , op1 , op2 ) ;
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 ( ) ;
}
2014-12-03 23:02:02 +08:00
ZEND_VM_HANDLER ( 4 , ZEND_DIV , CONST | TMPVAR | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
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 ) ,
2014-12-14 06:06:14 +08:00
GET_OP2_ZVAL_PTR ( BP_VAR_R ) ) ;
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 ( ) ;
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 5 , ZEND_MOD , CONST | TMPVAR | CV , CONST | TMPVAR | 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 ;
2015-03-17 23:53:19 +08:00
zval * op1 , * op2 , * result ;
op1 = GET_OP1_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
op2 = GET_OP2_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_LONG ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_LONG ) ) {
result = EX_VAR ( opline - > result . var ) ;
if ( UNEXPECTED ( Z_LVAL_P ( op2 ) = = 0 ) ) {
// TODO: change into exception ???
SAVE_OPLINE ( ) ;
zend_error ( E_WARNING , " Division by zero " ) ;
ZVAL_FALSE ( result ) ;
} else if ( UNEXPECTED ( Z_LVAL_P ( op2 ) = = - 1 ) ) {
/* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
ZVAL_LONG ( result , 0 ) ;
} else {
ZVAL_LONG ( result , Z_LVAL_P ( op1 ) % Z_LVAL_P ( op2 ) ) ;
}
ZEND_VM_NEXT_OPCODE ( ) ;
}
}
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2015-03-17 23:53:19 +08:00
if ( OP1_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op1 ) = = IS_UNDEF ) ) {
op1 = GET_OP1_UNDEF_CV ( op1 , BP_VAR_R ) ;
}
if ( OP2_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op2 ) = = IS_UNDEF ) ) {
op2 = GET_OP2_UNDEF_CV ( op2 , BP_VAR_R ) ;
}
mod_function ( EX_VAR ( opline - > result . var ) , op1 , op2 ) ;
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 ( ) ;
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 6 , ZEND_SL , CONST | TMPVAR | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-02-10 14:04:30 +08:00
shift_left_function ( EX_VAR ( opline - > result . var ) ,
2014-12-06 07:14:45 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
2014-12-14 06:06:14 +08:00
GET_OP2_ZVAL_PTR ( BP_VAR_R ) ) ;
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 ( ) ;
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 7 , ZEND_SR , CONST | TMPVAR | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-02-10 14:04:30 +08:00
shift_right_function ( EX_VAR ( opline - > result . var ) ,
2014-12-06 07:14:45 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
2014-12-14 06:06:14 +08:00
GET_OP2_ZVAL_PTR ( BP_VAR_R ) ) ;
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 ( ) ;
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 8 , ZEND_CONCAT , CONST | TMPVAR | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-02-10 14:04:30 +08:00
concat_function ( EX_VAR ( opline - > result . var ) ,
2014-12-06 07:14:45 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
2014-12-14 06:06:14 +08:00
GET_OP2_ZVAL_PTR ( BP_VAR_R ) ) ;
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 ) ,
2014-12-14 06:06:14 +08:00
GET_OP2_ZVAL_PTR_DEREF ( BP_VAR_R ) ) ;
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 ) ,
2014-12-14 06:06:14 +08:00
GET_OP2_ZVAL_PTR_DEREF ( BP_VAR_R ) ) ;
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 ( ) ;
}
2014-12-03 23:02:02 +08:00
ZEND_VM_HANDLER ( 17 , ZEND_IS_EQUAL , CONST | TMPVAR | CV , CONST | TMPVAR | 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 ;
2015-03-17 23:53:19 +08:00
zval * op1 , * op2 , * result ;
op1 = GET_OP1_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
op2 = GET_OP2_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_LONG ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_LONG ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , Z_LVAL_P ( op1 ) = = Z_LVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_DOUBLE ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , ( double ) Z_LVAL_P ( op1 ) = = Z_DVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
} else if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_DOUBLE ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_DOUBLE ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , Z_DVAL_P ( op1 ) = = Z_DVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_LONG ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , Z_DVAL_P ( op1 ) = = ( ( double ) Z_LVAL_P ( op2 ) ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
} else if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_STRING ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_STRING ) ) {
if ( Z_STR_P ( op1 ) = = Z_STR_P ( op2 ) ) {
ZVAL_TRUE ( EX_VAR ( opline - > result . var ) ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( Z_STRVAL_P ( op1 ) [ 0 ] > ' 9 ' | | Z_STRVAL_P ( op2 ) [ 0 ] > ' 9 ' ) {
if ( Z_STRLEN_P ( op1 ) ! = Z_STRLEN_P ( op2 ) ) {
ZVAL_FALSE ( EX_VAR ( opline - > result . var ) ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , memcmp ( Z_STRVAL_P ( op1 ) , Z_STRVAL_P ( op2 ) , Z_STRLEN_P ( op1 ) ) = = 0 ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
} else {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , zendi_smart_strcmp ( op1 , op2 ) = = 0 ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
}
}
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2015-03-17 23:53:19 +08:00
if ( OP1_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op1 ) = = IS_UNDEF ) ) {
op1 = GET_OP1_UNDEF_CV ( op1 , BP_VAR_R ) ;
}
if ( OP2_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op2 ) = = IS_UNDEF ) ) {
op2 = GET_OP2_UNDEF_CV ( op2 , BP_VAR_R ) ;
}
result = EX_VAR ( opline - > result . var ) ;
compare_function ( result , op1 , op2 ) ;
ZVAL_BOOL ( result , Z_LVAL_P ( result ) = = 0 ) ;
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 ( ) ;
}
2014-12-03 23:02:02 +08:00
ZEND_VM_HANDLER ( 18 , ZEND_IS_NOT_EQUAL , CONST | TMPVAR | CV , CONST | TMPVAR | 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 ;
2015-03-17 23:53:19 +08:00
zval * op1 , * op2 , * result ;
op1 = GET_OP1_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
op2 = GET_OP2_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_LONG ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_LONG ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , Z_LVAL_P ( op1 ) ! = Z_LVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_DOUBLE ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , ( double ) Z_LVAL_P ( op1 ) ! = Z_DVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
} else if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_DOUBLE ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_DOUBLE ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , Z_DVAL_P ( op1 ) ! = Z_DVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_LONG ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , Z_DVAL_P ( op1 ) ! = ( ( double ) Z_LVAL_P ( op2 ) ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
} else if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_STRING ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_STRING ) ) {
if ( Z_STR_P ( op1 ) = = Z_STR_P ( op2 ) ) {
ZVAL_FALSE ( EX_VAR ( opline - > result . var ) ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( Z_STRVAL_P ( op1 ) [ 0 ] > ' 9 ' | | Z_STRVAL_P ( op2 ) [ 0 ] > ' 9 ' ) {
if ( Z_STRLEN_P ( op1 ) ! = Z_STRLEN_P ( op2 ) ) {
ZVAL_TRUE ( EX_VAR ( opline - > result . var ) ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , memcmp ( Z_STRVAL_P ( op1 ) , Z_STRVAL_P ( op2 ) , Z_STRLEN_P ( op1 ) ) ! = 0 ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
} else {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , zendi_smart_strcmp ( op1 , op2 ) ! = 0 ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
}
}
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2015-03-17 23:53:19 +08:00
if ( OP1_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op1 ) = = IS_UNDEF ) ) {
op1 = GET_OP1_UNDEF_CV ( op1 , BP_VAR_R ) ;
}
if ( OP2_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op2 ) = = IS_UNDEF ) ) {
op2 = GET_OP2_UNDEF_CV ( op2 , BP_VAR_R ) ;
}
result = EX_VAR ( opline - > result . var ) ;
compare_function ( result , op1 , op2 ) ;
ZVAL_BOOL ( result , Z_LVAL_P ( result ) ! = 0 ) ;
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 ( ) ;
}
2014-12-03 23:02:02 +08:00
ZEND_VM_HANDLER ( 19 , ZEND_IS_SMALLER , CONST | TMPVAR | CV , CONST | TMPVAR | 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 ;
2015-03-17 23:53:19 +08:00
zval * op1 , * op2 , * result ;
op1 = GET_OP1_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
op2 = GET_OP2_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_LONG ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_LONG ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , Z_LVAL_P ( op1 ) < Z_LVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_DOUBLE ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , ( double ) Z_LVAL_P ( op1 ) < Z_DVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
} else if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_DOUBLE ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_DOUBLE ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , Z_DVAL_P ( op1 ) < Z_DVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_LONG ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , Z_DVAL_P ( op1 ) < ( ( double ) Z_LVAL_P ( op2 ) ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
}
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2015-03-17 23:53:19 +08:00
if ( OP1_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op1 ) = = IS_UNDEF ) ) {
op1 = GET_OP1_UNDEF_CV ( op1 , BP_VAR_R ) ;
}
if ( OP2_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op2 ) = = IS_UNDEF ) ) {
op2 = GET_OP2_UNDEF_CV ( op2 , BP_VAR_R ) ;
}
result = EX_VAR ( opline - > result . var ) ;
compare_function ( result , op1 , op2 ) ;
ZVAL_BOOL ( result , Z_LVAL_P ( result ) < 0 ) ;
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 ( ) ;
}
2014-12-03 23:02:02 +08:00
ZEND_VM_HANDLER ( 20 , ZEND_IS_SMALLER_OR_EQUAL , CONST | TMPVAR | CV , CONST | TMPVAR | 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 ;
2015-03-17 23:53:19 +08:00
zval * op1 , * op2 , * result ;
op1 = GET_OP1_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
op2 = GET_OP2_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_LONG ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_LONG ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , Z_LVAL_P ( op1 ) < = Z_LVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_DOUBLE ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , ( double ) Z_LVAL_P ( op1 ) < = Z_DVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
} else if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_DOUBLE ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_DOUBLE ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , Z_DVAL_P ( op1 ) < = Z_DVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_LONG ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , Z_DVAL_P ( op1 ) < = ( ( double ) Z_LVAL_P ( op2 ) ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
}
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2015-03-17 23:53:19 +08:00
if ( OP1_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op1 ) = = IS_UNDEF ) ) {
op1 = GET_OP1_UNDEF_CV ( op1 , BP_VAR_R ) ;
}
if ( OP2_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op2 ) = = IS_UNDEF ) ) {
op2 = GET_OP2_UNDEF_CV ( op2 , BP_VAR_R ) ;
}
result = EX_VAR ( opline - > result . var ) ;
compare_function ( result , op1 , op2 ) ;
ZVAL_BOOL ( result , Z_LVAL_P ( result ) < = 0 ) ;
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 ( ) ;
}
2015-01-19 15:12:39 +08:00
ZEND_VM_HANDLER ( 170 , ZEND_SPACESHIP , CONST | TMPVAR | CV , CONST | TMPVAR | CV )
{
USE_OPLINE
zend_free_op free_op1 , free_op2 ;
zval * result = EX_VAR ( opline - > result . var ) ;
SAVE_OPLINE ( ) ;
compare_function ( result ,
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
GET_OP2_ZVAL_PTR ( BP_VAR_R ) ) ;
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 9 , ZEND_BW_OR , CONST | TMPVAR | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-02-10 14:04:30 +08:00
bitwise_or_function ( EX_VAR ( opline - > result . var ) ,
2014-12-06 07:14:45 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
2014-12-14 06:06:14 +08:00
GET_OP2_ZVAL_PTR ( BP_VAR_R ) ) ;
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 ( ) ;
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 10 , ZEND_BW_AND , CONST | TMPVAR | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-02-10 14:04:30 +08:00
bitwise_and_function ( EX_VAR ( opline - > result . var ) ,
2014-12-06 07:14:45 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
2014-12-14 06:06:14 +08:00
GET_OP2_ZVAL_PTR ( BP_VAR_R ) ) ;
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 ( ) ;
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 11 , ZEND_BW_XOR , CONST | TMPVAR | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-02-10 14:04:30 +08:00
bitwise_xor_function ( EX_VAR ( opline - > result . var ) ,
2014-12-06 07:14:45 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
2014-12-14 06:06:14 +08:00
GET_OP2_ZVAL_PTR ( BP_VAR_R ) ) ;
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 ( ) ;
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 14 , ZEND_BOOL_XOR , CONST | TMPVAR | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-02-10 14:04:30 +08:00
boolean_xor_function ( EX_VAR ( opline - > result . var ) ,
2014-12-06 07:14:45 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
2014-12-14 06:06:14 +08:00
GET_OP2_ZVAL_PTR ( BP_VAR_R ) ) ;
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 ( ) ;
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 12 , ZEND_BW_NOT , CONST | TMPVAR | 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
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-12-14 06:06:14 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ) ;
2004-10-23 05:42:14 +08:00
FREE_OP1 ( ) ;
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-12-05 22:04:15 +08:00
ZEND_VM_HANDLER ( 13 , ZEND_BOOL_NOT , CONST | TMPVAR | CV , ANY )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2014-12-05 22:04:15 +08:00
zval * val ;
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-12-05 22:04:15 +08:00
val = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2015-01-03 17:22:58 +08:00
if ( Z_TYPE_P ( val ) = = IS_TRUE ) {
2014-12-05 22:04:15 +08:00
ZVAL_FALSE ( EX_VAR ( opline - > result . var ) ) ;
} else if ( EXPECTED ( Z_TYPE_P ( val ) < = IS_TRUE ) ) {
ZVAL_TRUE ( EX_VAR ( opline - > result . var ) ) ;
} else {
2014-12-14 06:06:14 +08:00
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , ! i_zend_is_true ( val ) ) ;
2014-12-05 22:04:15 +08:00
FREE_OP1 ( ) ;
CHECK_EXCEPTION ( ) ;
}
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2015-03-14 02:10:09 +08:00
ZEND_VM_HELPER_EX ( zend_binary_assign_op_obj_helper , VAR | UNUSED | CV , CONST | TMPVAR | CV , binary_op_type binary_op )
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 ;
2015-03-13 01:39:04 +08:00
zval * object ;
zval * property ;
2014-03-05 19:33:31 +08:00
zval * value ;
2014-10-21 04:56:48 +08:00
zval * zptr ;
2004-10-23 05:42:14 +08:00
2015-03-13 01:39:04 +08:00
SAVE_OPLINE ( ) ;
object = GET_OP1_OBJ_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
property = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2014-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( object = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use string offset as an object " ) ;
FREE_UNFETCHED_OP ( ( opline + 1 ) - > op1_type , ( opline + 1 ) - > op1 . var ) ;
FREE_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2009-03-18 20:53:17 +08:00
}
2014-12-09 08:05:06 +08:00
do {
2014-12-09 20:15:24 +08:00
value = get_zval_ptr ( ( opline + 1 ) - > op1_type , ( opline + 1 ) - > op1 , execute_data , & free_op_data1 , BP_VAR_R ) ;
2014-12-09 17:17:55 +08:00
2014-12-09 08:05:06 +08:00
if ( OP1_TYPE ! = IS_UNUSED & & UNEXPECTED ( Z_TYPE_P ( object ) ! = IS_OBJECT ) ) {
2015-02-26 04:20:47 +08:00
ZVAL_DEREF ( object ) ;
if ( UNEXPECTED ( ! make_real_object ( object ) ) ) {
2014-12-09 08:05:06 +08:00
zend_error ( E_WARNING , " Attempt to assign property of non-object " ) ;
2014-12-09 22:07:12 +08:00
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
2014-12-09 08:05:06 +08:00
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
}
break ;
}
}
2014-03-05 19:33:31 +08:00
2004-10-23 05:42:14 +08:00
/* here we are sure we are dealing with an object */
2014-12-09 20:15:24 +08:00
if ( EXPECTED ( Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr )
2015-02-25 06:52:35 +08:00
& & EXPECTED ( ( zptr = Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ( object , property , BP_VAR_RW , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( property ) ) : NULL ) ) ) ! = NULL ) ) {
2014-10-21 04:56:48 +08:00
ZVAL_DEREF ( zptr ) ;
SEPARATE_ZVAL_NOREF ( zptr ) ;
2004-10-23 05:42:14 +08:00
2014-12-14 06:06:14 +08:00
binary_op ( zptr , zptr , value ) ;
2014-12-09 22:07:12 +08:00
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
2014-10-21 04:56:48 +08:00
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , zptr ) ;
}
} else {
2014-12-09 20:15:24 +08:00
zval * z ;
2015-03-10 15:49:02 +08:00
zval rv , obj ;
2004-10-23 05:42:14 +08:00
2015-03-10 17:18:54 +08:00
ZVAL_OBJ ( & obj , Z_OBJ_P ( object ) ) ;
Z_ADDREF ( obj ) ;
2015-03-10 15:49:02 +08:00
if ( Z_OBJ_HT ( obj ) - > read_property & &
( z = Z_OBJ_HT ( obj ) - > read_property ( & obj , property , BP_VAR_R , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( property ) ) : NULL ) , & rv ) ) ! = NULL ) {
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 ;
2014-12-14 06:06:14 +08:00
zval * value = Z_OBJ_HT_P ( z ) - > get ( z , & rv ) ;
2004-10-23 05:42:14 +08:00
2007-10-07 13:22:07 +08:00
if ( Z_REFCOUNT_P ( z ) = = 0 ) {
2014-12-14 06:06:14 +08:00
zend_objects_store_del ( Z_OBJ_P ( z ) ) ;
2005-04-16 01:15:18 +08:00
}
2014-04-15 11:05:03 +08:00
ZVAL_COPY_VALUE ( z , value ) ;
2005-04-16 01:15:18 +08:00
}
2015-03-08 20:22:02 +08:00
zptr = z ;
2014-12-09 20:15:24 +08:00
ZVAL_DEREF ( z ) ;
SEPARATE_ZVAL_NOREF ( z ) ;
2014-12-14 06:06:14 +08:00
binary_op ( z , z , value ) ;
2015-03-10 15:49:02 +08:00
Z_OBJ_HT ( obj ) - > write_property ( & obj , property , z , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( property ) ) : NULL ) ) ;
2014-12-09 22:07:12 +08:00
if ( UNEXPECTED ( 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
}
2015-03-08 20:22:02 +08:00
zval_ptr_dtor ( zptr ) ;
2005-04-16 01:15:18 +08:00
} else {
zend_error ( E_WARNING , " Attempt to assign property of non-object " ) ;
2014-12-09 22:07:12 +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
}
}
2015-03-10 17:18:54 +08:00
OBJ_RELEASE ( Z_OBJ ( obj ) ) ;
2004-10-23 05:42:14 +08:00
}
2014-12-09 08:05:06 +08:00
} while ( 0 ) ;
2004-10-23 05:42:14 +08:00
2014-12-20 00:43:17 +08:00
FREE_OP ( free_op_data1 ) ;
FREE_OP2 ( ) ;
2004-10-23 05:42:14 +08:00
FREE_OP1_VAR_PTR ( ) ;
/* assign_obj has two opcodes! */
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_INC_OPCODE ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2015-03-14 02:10:09 +08:00
ZEND_VM_HELPER_EX ( zend_binary_assign_op_dim_helper , VAR | UNUSED | CV , CONST | TMPVAR | UNUSED | CV , binary_op_type binary_op )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2014-10-21 23:30:43 +08:00
zend_free_op free_op1 , free_op2 , free_op_data1 ;
zval * var_ptr , rv ;
2014-12-06 08:03:48 +08:00
zval * value , * container , * dim ;
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 ) ;
2014-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use string offset as an array " ) ;
FREE_UNFETCHED_OP ( ( opline + 1 ) - > op1_type , ( opline + 1 ) - > op1 . var ) ;
FREE_UNFETCHED_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2014-10-21 23:30:43 +08:00
}
2014-12-06 08:03:48 +08:00
dim = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2014-12-09 20:15:24 +08:00
do {
if ( OP1_TYPE = = IS_UNUSED | | UNEXPECTED ( Z_TYPE_P ( container ) ! = IS_ARRAY ) ) {
if ( OP1_TYPE ! = IS_UNUSED ) {
ZVAL_DEREF ( container ) ;
}
# if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
if ( OP1_TYPE = = IS_UNUSED | | EXPECTED ( Z_TYPE_P ( container ) = = IS_OBJECT ) ) {
value = get_zval_ptr ( ( opline + 1 ) - > op1_type , ( opline + 1 ) - > op1 , execute_data , & free_op_data1 , BP_VAR_R ) ;
2014-12-14 06:06:14 +08:00
zend_binary_assign_op_obj_dim ( container , dim , value , UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ? EX_VAR ( opline - > result . var ) : NULL , binary_op ) ;
2014-12-09 20:15:24 +08:00
break ;
}
# endif
}
2004-10-23 05:42:14 +08:00
2014-12-14 06:06:14 +08:00
zend_fetch_dimension_address_RW ( & rv , container , dim , OP2_TYPE ) ;
2014-12-09 20:15:24 +08:00
value = get_zval_ptr ( ( opline + 1 ) - > op1_type , ( opline + 1 ) - > op1 , execute_data , & free_op_data1 , BP_VAR_R ) ;
ZEND_ASSERT ( Z_TYPE ( rv ) = = IS_INDIRECT ) ;
var_ptr = Z_INDIRECT ( rv ) ;
2004-10-23 05:42:14 +08:00
2014-12-09 20:15:24 +08:00
if ( UNEXPECTED ( var_ptr = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use assign-op operators with overloaded objects nor string offsets " ) ;
FREE_OP2 ( ) ;
FREE_OP ( free_op_data1 ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
2014-12-09 20:15:24 +08:00
if ( UNEXPECTED ( var_ptr = = & EG ( error_zval ) ) ) {
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
}
} else {
ZVAL_DEREF ( var_ptr ) ;
SEPARATE_ZVAL_NOREF ( var_ptr ) ;
2004-10-23 05:42:14 +08:00
2014-12-14 06:06:14 +08:00
binary_op ( var_ptr , var_ptr , value ) ;
2014-12-09 20:15:24 +08:00
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , var_ptr ) ;
}
2014-10-21 15:43:13 +08:00
}
2014-12-09 20:15:24 +08:00
} while ( 0 ) ;
2014-04-08 06:25:49 +08:00
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2014-04-08 06:25:49 +08:00
FREE_OP ( free_op_data1 ) ;
FREE_OP1_VAR_PTR ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_INC_OPCODE ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
2015-03-14 02:10:09 +08:00
ZEND_VM_HELPER_EX ( zend_binary_assign_op_helper , VAR | CV , CONST | TMPVAR | CV , binary_op_type binary_op )
2014-04-08 06:25:49 +08:00
{
USE_OPLINE
zend_free_op free_op1 , free_op2 ;
zval * var_ptr ;
zval * value ;
SAVE_OPLINE ( ) ;
2014-12-06 07:14:45 +08:00
value = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2014-04-08 06:25:49 +08:00
var_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_RW ) ;
2014-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( var_ptr = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use assign-op operators with overloaded objects nor string offsets " ) ;
FREE_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2014-04-08 06:25:49 +08:00
}
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( var_ptr = = & EG ( error_zval ) ) ) {
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
}
2014-10-21 15:43:13 +08:00
} else {
ZVAL_DEREF ( var_ptr ) ;
SEPARATE_ZVAL_NOREF ( var_ptr ) ;
2014-04-08 06:25:49 +08:00
2014-12-14 06:06:14 +08:00
binary_op ( var_ptr , var_ptr , value ) ;
2014-04-08 06:25:49 +08:00
2014-10-21 15:43:13 +08:00
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
FREE_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 23 , ZEND_ASSIGN_ADD , VAR | UNUSED | CV , CONST | TMPVAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
2014-12-08 23:11:14 +08:00
# if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
USE_OPLINE
2014-12-06 08:03:48 +08:00
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , add_function ) ;
2014-12-06 08:03:48 +08:00
}
# endif
if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
2014-04-08 06:25:49 +08:00
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 ) ;
}
2014-12-06 08:03:48 +08:00
# else
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , add_function ) ;
# endif
2004-10-23 05:42:14 +08:00
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 24 , ZEND_ASSIGN_SUB , VAR | UNUSED | CV , CONST | TMPVAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
2014-12-08 23:11:14 +08:00
# if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
USE_OPLINE
2014-12-06 08:03:48 +08:00
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , sub_function ) ;
2014-12-06 08:03:48 +08:00
}
# endif
if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
2014-04-08 06:25:49 +08:00
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 ) ;
}
2014-12-06 08:03:48 +08:00
# else
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , sub_function ) ;
# endif
2004-10-23 05:42:14 +08:00
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 25 , ZEND_ASSIGN_MUL , VAR | UNUSED | CV , CONST | TMPVAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
2014-12-08 23:11:14 +08:00
# if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
USE_OPLINE
2014-12-06 08:03:48 +08:00
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , mul_function ) ;
2014-12-06 08:03:48 +08:00
}
# endif
if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
2014-04-08 06:25:49 +08:00
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 ) ;
}
2014-12-06 08:03:48 +08:00
# else
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , mul_function ) ;
# endif
2004-10-23 05:42:14 +08:00
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 26 , ZEND_ASSIGN_DIV , VAR | UNUSED | CV , CONST | TMPVAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
2014-12-08 23:11:14 +08:00
# if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
USE_OPLINE
2014-12-06 08:03:48 +08:00
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , div_function ) ;
2014-12-06 08:03:48 +08:00
}
# endif
if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
2014-04-08 06:25:49 +08:00
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 ) ;
}
2014-12-06 08:03:48 +08:00
# else
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , div_function ) ;
# endif
2004-10-23 05:42:14 +08:00
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 27 , ZEND_ASSIGN_MOD , VAR | UNUSED | CV , CONST | TMPVAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
2014-12-08 23:11:14 +08:00
# if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
USE_OPLINE
2014-12-06 08:03:48 +08:00
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , mod_function ) ;
2014-12-06 08:03:48 +08:00
}
# endif
if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
2014-04-08 06:25:49 +08:00
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 ) ;
}
2014-12-06 08:03:48 +08:00
# else
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , mod_function ) ;
# endif
2004-10-23 05:42:14 +08:00
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 28 , ZEND_ASSIGN_SL , VAR | UNUSED | CV , CONST | TMPVAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
2014-12-08 23:11:14 +08:00
# if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
USE_OPLINE
2014-12-06 08:03:48 +08:00
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , shift_left_function ) ;
2014-12-06 08:03:48 +08:00
}
# endif
if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
2014-04-08 06:25:49 +08:00
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 ) ;
}
2014-12-06 08:03:48 +08:00
# else
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , shift_left_function ) ;
# endif
2004-10-23 05:42:14 +08:00
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 29 , ZEND_ASSIGN_SR , VAR | UNUSED | CV , CONST | TMPVAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
2014-12-08 23:11:14 +08:00
# if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
USE_OPLINE
2014-12-06 08:03:48 +08:00
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , shift_right_function ) ;
2014-12-06 08:03:48 +08:00
}
# endif
if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
2014-04-08 06:25:49 +08:00
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 ) ;
}
2014-12-06 08:03:48 +08:00
# else
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , shift_right_function ) ;
# endif
2004-10-23 05:42:14 +08:00
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 30 , ZEND_ASSIGN_CONCAT , VAR | UNUSED | CV , CONST | TMPVAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
2014-12-08 23:11:14 +08:00
# if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
USE_OPLINE
2014-12-06 08:03:48 +08:00
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , concat_function ) ;
2014-12-06 08:03:48 +08:00
}
# endif
if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
2014-04-08 06:25:49 +08:00
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 ) ;
}
2014-12-06 08:03:48 +08:00
# else
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , concat_function ) ;
# endif
2004-10-23 05:42:14 +08:00
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 31 , ZEND_ASSIGN_BW_OR , VAR | UNUSED | CV , CONST | TMPVAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
2014-12-08 23:11:14 +08:00
# if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
USE_OPLINE
2014-12-06 08:03:48 +08:00
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , bitwise_or_function ) ;
2014-12-06 08:03:48 +08:00
}
# endif
if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
2014-04-08 06:25:49 +08:00
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 ) ;
}
2014-12-06 08:03:48 +08:00
# else
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , bitwise_or_function ) ;
# endif
2004-10-23 05:42:14 +08:00
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 32 , ZEND_ASSIGN_BW_AND , VAR | UNUSED | CV , CONST | TMPVAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
2014-12-08 23:11:14 +08:00
# if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
USE_OPLINE
2014-12-06 08:03:48 +08:00
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , bitwise_and_function ) ;
2014-12-06 08:03:48 +08:00
}
# endif
if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
2014-04-08 06:25:49 +08:00
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 ) ;
}
2014-12-06 08:03:48 +08:00
# else
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , bitwise_and_function ) ;
# endif
2004-10-23 05:42:14 +08:00
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 33 , ZEND_ASSIGN_BW_XOR , VAR | UNUSED | CV , CONST | TMPVAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
2014-12-08 23:11:14 +08:00
# if !defined(ZEND_VM_SPEC) || (OP2_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
USE_OPLINE
2014-12-06 08:03:48 +08:00
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
2014-04-08 06:25:49 +08:00
if ( EXPECTED ( opline - > extended_value = = 0 ) ) {
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_helper , binary_op , bitwise_xor_function ) ;
2014-12-06 08:03:48 +08:00
}
# endif
if ( EXPECTED ( opline - > extended_value = = ZEND_ASSIGN_DIM ) ) {
2014-04-08 06:25:49 +08:00
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 ) ;
}
2014-12-06 08:03:48 +08:00
# else
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_binary_assign_op_dim_helper , binary_op , bitwise_xor_function ) ;
# endif
2004-10-23 05:42:14 +08:00
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HELPER_EX ( zend_pre_incdec_property_helper , VAR | UNUSED | CV , CONST | TMPVAR | CV , incdec_t incdec_op )
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 ;
zval * object ;
2010-04-20 19:16:39 +08:00
zval * property ;
2014-02-10 14:04:30 +08:00
zval * retval ;
2014-10-21 04:56:48 +08:00
zval * zptr ;
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 = 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-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( object = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
FREE_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2009-03-18 20:53:17 +08:00
}
2014-12-09 08:05:06 +08:00
do {
if ( OP1_TYPE ! = IS_UNUSED & & UNEXPECTED ( Z_TYPE_P ( object ) ! = IS_OBJECT ) ) {
2015-02-26 04:20:47 +08:00
ZVAL_DEREF ( object ) ;
if ( UNEXPECTED ( ! make_real_object ( object ) ) ) {
2014-12-09 08:05:06 +08:00
zend_error ( E_WARNING , " Attempt to increment/decrement property of non-object " ) ;
2014-12-09 22:07:12 +08:00
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
2014-12-09 08:05:06 +08:00
ZVAL_NULL ( retval ) ;
}
break ;
}
2004-10-23 05:42:14 +08:00
}
2014-12-09 08:05:06 +08:00
/* here we are sure we are dealing with an object */
2004-10-23 05:42:14 +08:00
2014-12-09 08:05:06 +08:00
if ( EXPECTED ( Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr )
2015-02-25 06:52:35 +08:00
& & EXPECTED ( ( zptr = Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ( object , property , BP_VAR_RW , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( property ) ) : NULL ) ) ) ! = NULL ) ) {
2004-10-23 05:42:14 +08:00
2014-12-09 08:05:06 +08:00
ZVAL_DEREF ( zptr ) ;
SEPARATE_ZVAL_NOREF ( zptr ) ;
2004-10-23 05:42:14 +08:00
2014-12-09 08:05:06 +08:00
incdec_op ( zptr ) ;
2014-12-09 22:07:12 +08:00
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
2014-12-09 08:05:06 +08:00
ZVAL_COPY ( retval , zptr ) ;
}
} else {
zval rv ;
2014-02-27 19:40:13 +08:00
2014-12-09 08:05:06 +08:00
if ( Z_OBJ_HT_P ( object ) - > read_property & & Z_OBJ_HT_P ( object ) - > write_property ) {
2015-03-10 15:49:02 +08:00
zval * z , obj ;
2015-03-10 17:18:54 +08:00
ZVAL_OBJ ( & obj , Z_OBJ_P ( object ) ) ;
Z_ADDREF ( obj ) ;
2015-03-10 15:49:02 +08:00
z = Z_OBJ_HT ( obj ) - > read_property ( & obj , property , BP_VAR_R , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( property ) ) : NULL ) , & rv ) ;
2004-10-23 05:42:14 +08:00
2014-12-09 08:05:06 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( z ) = = IS_OBJECT ) & & Z_OBJ_HT_P ( z ) - > get ) {
zval rv ;
2014-12-14 06:06:14 +08:00
zval * value = Z_OBJ_HT_P ( z ) - > get ( z , & rv ) ;
2004-10-23 05:42:14 +08:00
2014-12-09 08:05:06 +08:00
if ( Z_REFCOUNT_P ( z ) = = 0 ) {
2014-12-14 06:06:14 +08:00
zend_objects_store_del ( Z_OBJ_P ( z ) ) ;
2014-12-09 08:05:06 +08:00
}
ZVAL_COPY_VALUE ( z , value ) ;
}
2014-12-09 20:15:24 +08:00
ZVAL_DEREF ( z ) ;
SEPARATE_ZVAL_NOREF ( z ) ;
2014-12-09 08:05:06 +08:00
incdec_op ( z ) ;
2014-12-09 22:07:12 +08:00
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
2014-12-09 20:15:24 +08:00
ZVAL_COPY ( retval , z ) ;
}
2015-03-10 15:49:02 +08:00
Z_OBJ_HT ( obj ) - > write_property ( & obj , property , z , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( property ) ) : NULL ) ) ;
2015-03-10 17:18:54 +08:00
OBJ_RELEASE ( Z_OBJ ( obj ) ) ;
2014-12-09 08:05:06 +08:00
zval_ptr_dtor ( z ) ;
} else {
zend_error ( E_WARNING , " Attempt to increment/decrement property of non-object " ) ;
2014-12-09 22:07:12 +08:00
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
2014-12-09 08:05:06 +08:00
ZVAL_NULL ( retval ) ;
2005-04-16 01:15:18 +08:00
}
2004-10-23 05:42:14 +08:00
}
}
2014-12-09 08:05:06 +08:00
} while ( 0 ) ;
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 ( ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 132 , ZEND_PRE_INC_OBJ , VAR | UNUSED | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_pre_incdec_property_helper , incdec_op , increment_function ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 133 , ZEND_PRE_DEC_OBJ , VAR | UNUSED | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_pre_incdec_property_helper , incdec_op , decrement_function ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HELPER_EX ( zend_post_incdec_property_helper , VAR | UNUSED | CV , CONST | TMPVAR | CV , incdec_t incdec_op )
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 ;
zval * object ;
2010-04-20 19:16:39 +08:00
zval * property ;
zval * retval ;
2014-10-21 04:56:48 +08:00
zval * zptr ;
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 = 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-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( object = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
FREE_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2009-03-18 20:53:17 +08:00
}
2014-12-09 08:05:06 +08:00
do {
if ( OP1_TYPE ! = IS_UNUSED & & UNEXPECTED ( Z_TYPE_P ( object ) ! = IS_OBJECT ) ) {
2015-02-26 04:20:47 +08:00
ZVAL_DEREF ( object ) ;
if ( UNEXPECTED ( ! make_real_object ( object ) ) ) {
2014-12-09 08:05:06 +08:00
zend_error ( E_WARNING , " Attempt to increment/decrement property of non-object " ) ;
ZVAL_NULL ( retval ) ;
break ;
}
}
2004-10-23 05:42:14 +08:00
2014-12-09 08:05:06 +08:00
/* here we are sure we are dealing with an object */
2004-10-23 05:42:14 +08:00
2014-12-09 08:05:06 +08:00
if ( EXPECTED ( Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr )
2015-02-25 06:52:35 +08:00
& & EXPECTED ( ( zptr = Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ( object , property , BP_VAR_RW , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( property ) ) : NULL ) ) ) ! = NULL ) ) {
2004-10-23 05:42:14 +08:00
2014-12-09 08:05:06 +08:00
ZVAL_DEREF ( zptr ) ;
ZVAL_COPY_VALUE ( retval , zptr ) ;
zval_opt_copy_ctor ( zptr ) ;
incdec_op ( zptr ) ;
} else {
if ( Z_OBJ_HT_P ( object ) - > read_property & & Z_OBJ_HT_P ( object ) - > write_property ) {
2015-03-10 15:49:02 +08:00
zval rv , obj ;
zval * z ;
2014-12-09 08:05:06 +08:00
zval z_copy ;
2015-03-10 17:18:54 +08:00
ZVAL_OBJ ( & obj , Z_OBJ_P ( object ) ) ;
Z_ADDREF ( obj ) ;
2015-03-10 15:49:02 +08:00
z = Z_OBJ_HT ( obj ) - > read_property ( & obj , property , BP_VAR_R , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( property ) ) : NULL ) , & rv ) ;
2014-12-09 08:05:06 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( z ) = = IS_OBJECT ) & & Z_OBJ_HT_P ( z ) - > get ) {
zval rv ;
2014-12-14 06:06:14 +08:00
zval * value = Z_OBJ_HT_P ( z ) - > get ( z , & rv ) ;
2014-12-09 08:05:06 +08:00
if ( Z_REFCOUNT_P ( z ) = = 0 ) {
2014-12-14 06:06:14 +08:00
zend_objects_store_del ( Z_OBJ_P ( z ) ) ;
2014-12-09 08:05:06 +08:00
}
ZVAL_COPY_VALUE ( z , value ) ;
2005-04-16 01:15:18 +08:00
}
2014-12-09 08:05:06 +08:00
ZVAL_DUP ( retval , z ) ;
ZVAL_DUP ( & z_copy , z ) ;
incdec_op ( & z_copy ) ;
if ( Z_REFCOUNTED_P ( z ) ) Z_ADDREF_P ( z ) ;
2015-03-10 15:49:02 +08:00
Z_OBJ_HT ( obj ) - > write_property ( & obj , property , & z_copy , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( property ) ) : NULL ) ) ;
2015-03-10 17:18:54 +08:00
OBJ_RELEASE ( Z_OBJ ( obj ) ) ;
2014-12-09 08:05:06 +08:00
zval_ptr_dtor ( & z_copy ) ;
zval_ptr_dtor ( z ) ;
} else {
zend_error ( E_WARNING , " Attempt to increment/decrement property of non-object " ) ;
ZVAL_NULL ( retval ) ;
2004-10-23 05:42:14 +08:00
}
}
2014-12-09 08:05:06 +08:00
} while ( 0 ) ;
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 ( ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 134 , ZEND_POST_INC_OBJ , VAR | UNUSED | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
ZEND_VM_DISPATCH_TO_HELPER_EX ( zend_post_incdec_property_helper , incdec_op , increment_function ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 135 , ZEND_POST_DEC_OBJ , VAR | UNUSED | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
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
2015-03-17 23:53:19 +08:00
var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF ( BP_VAR_RW ) ;
2010-04-20 19:16:39 +08:00
2014-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( var_ptr = = NULL ) ) {
2015-03-17 23:53:19 +08:00
SAVE_OPLINE ( ) ;
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2014-09-08 19:46:45 +08:00
}
2014-08-26 01:24:55 +08:00
if ( EXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_LONG ) ) {
2015-03-17 23:53:19 +08:00
fast_long_increment_function ( var_ptr ) ;
2014-12-09 22:07:12 +08:00
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
2014-04-22 01:38:44 +08:00
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 ( var_ptr = = & EG ( error_zval ) ) ) {
2014-12-09 22:07:12 +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
}
ZEND_VM_NEXT_OPCODE ( ) ;
}
2015-03-17 23:53:19 +08:00
SAVE_OPLINE ( ) ;
if ( OP1_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_UNDEF ) ) {
var_ptr = GET_OP1_UNDEF_CV ( var_ptr , BP_VAR_RW ) ;
}
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-09-25 17:42:46 +08:00
increment_function ( var_ptr ) ;
2004-10-23 05:42:14 +08:00
2014-12-09 22:07:12 +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
}
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
2015-03-17 23:53:19 +08:00
var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF ( BP_VAR_RW ) ;
2010-04-20 19:16:39 +08:00
2014-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( var_ptr = = NULL ) ) {
2015-03-17 23:53:19 +08:00
SAVE_OPLINE ( ) ;
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2014-09-08 19:46:45 +08:00
}
2014-08-26 01:24:55 +08:00
if ( EXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_LONG ) ) {
2015-03-17 23:53:19 +08:00
fast_long_decrement_function ( var_ptr ) ;
2014-12-09 22:07:12 +08:00
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
2014-04-22 01:38:44 +08:00
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 ( var_ptr = = & EG ( error_zval ) ) ) {
2014-12-09 22:07:12 +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
}
ZEND_VM_NEXT_OPCODE ( ) ;
}
2015-03-17 23:53:19 +08:00
SAVE_OPLINE ( ) ;
if ( OP1_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_UNDEF ) ) {
var_ptr = GET_OP1_UNDEF_CV ( var_ptr , BP_VAR_RW ) ;
}
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-09-25 17:42:46 +08:00
decrement_function ( var_ptr ) ;
2004-10-23 05:42:14 +08:00
2014-12-09 22:07:12 +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
}
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-09-25 17:42:46 +08:00
zval * var_ptr ;
2010-04-20 19:16:39 +08:00
2015-03-17 23:53:19 +08:00
var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF ( BP_VAR_RW ) ;
2004-10-23 05:42:14 +08:00
2014-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( var_ptr = = NULL ) ) {
2015-03-17 23:53:19 +08:00
SAVE_OPLINE ( ) ;
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2014-09-08 19:46:45 +08:00
}
2014-08-26 01:24:55 +08:00
if ( EXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_LONG ) ) {
2014-04-22 01:38:44 +08:00
ZVAL_COPY_VALUE ( EX_VAR ( opline - > result . var ) , var_ptr ) ;
2015-03-17 23:53:19 +08:00
fast_long_increment_function ( var_ptr ) ;
2014-04-22 01:38:44 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
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
ZEND_VM_NEXT_OPCODE ( ) ;
}
2015-03-17 23:53:19 +08:00
SAVE_OPLINE ( ) ;
if ( OP1_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_UNDEF ) ) {
var_ptr = GET_OP1_UNDEF_CV ( var_ptr , BP_VAR_RW ) ;
}
2014-12-03 07:47:03 +08:00
ZVAL_DEREF ( var_ptr ) ;
ZVAL_COPY_VALUE ( EX_VAR ( opline - > result . var ) , var_ptr ) ;
zval_opt_copy_ctor ( var_ptr ) ;
2004-10-23 05:42:14 +08:00
2014-09-25 17:42:46 +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-09-25 17:42:46 +08:00
zval * var_ptr ;
2004-10-23 05:42:14 +08:00
2015-03-17 23:53:19 +08:00
var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF ( BP_VAR_RW ) ;
2010-04-20 19:16:39 +08:00
2014-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( var_ptr = = NULL ) ) {
2015-03-17 23:53:19 +08:00
SAVE_OPLINE ( ) ;
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2014-09-08 19:46:45 +08:00
}
2014-08-26 01:24:55 +08:00
if ( EXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_LONG ) ) {
2014-04-22 01:38:44 +08:00
ZVAL_COPY_VALUE ( EX_VAR ( opline - > result . var ) , var_ptr ) ;
2015-03-17 23:53:19 +08:00
fast_long_decrement_function ( var_ptr ) ;
2014-04-22 01:38:44 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
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
ZEND_VM_NEXT_OPCODE ( ) ;
}
2015-03-17 23:53:19 +08:00
SAVE_OPLINE ( ) ;
if ( OP1_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( var_ptr ) = = IS_UNDEF ) ) {
var_ptr = GET_OP1_UNDEF_CV ( var_ptr , BP_VAR_RW ) ;
}
2014-12-03 07:47:03 +08:00
ZVAL_DEREF ( var_ptr ) ;
ZVAL_COPY_VALUE ( EX_VAR ( opline - > result . var ) , var_ptr ) ;
zval_opt_copy_ctor ( var_ptr ) ;
2004-10-23 05:42:14 +08:00
2014-09-25 17:42:46 +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 ( ) ;
}
2014-12-05 20:07:49 +08:00
ZEND_VM_HANDLER ( 40 , ZEND_ECHO , CONST | TMPVAR | 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
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
zval * z ;
SAVE_OPLINE ( ) ;
2014-12-05 20:07:49 +08:00
z = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-02-23 19:36:38 +08:00
2014-12-05 20:07:49 +08:00
if ( Z_TYPE_P ( z ) = = IS_STRING ) {
zend_string * str = Z_STR_P ( z ) ;
if ( str - > len ! = 0 ) {
zend_write ( str - > val , str - > len ) ;
}
} else {
2014-12-14 06:06:14 +08:00
zend_string * str = _zval_get_string_func ( z ) ;
2014-12-05 20:07:49 +08:00
if ( str - > len ! = 0 ) {
zend_write ( str - > val , str - > len ) ;
}
zend_string_release ( str ) ;
}
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 ( ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HELPER_EX ( zend_fetch_var_address_helper , CONST | TMPVAR | 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 ) ;
2014-08-26 01:24:55 +08:00
zend_string_addref ( name ) ;
2014-06-03 04:36:31 +08:00
} 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 ) {
2015-01-13 08:32:51 +08:00
if ( OP1_TYPE = = IS_CONST & & CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) ) ) {
ce = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) ) ;
2015-02-25 06:52:35 +08:00
retval = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) + sizeof ( void * ) ) ;
2015-01-13 08:32:51 +08:00
/* check if static properties were destoyed */
if ( UNEXPECTED ( CE_STATIC_MEMBERS ( ce ) = = NULL ) ) {
zend_error_noreturn ( E_ERROR , " Access to undeclared static property: %s::$%s " , ce - > name - > val , name - > val ) ;
}
2015-01-13 14:33:15 +08:00
ZEND_VM_C_GOTO ( fetch_var_return ) ;
2015-01-13 08:32:51 +08:00
} else if ( CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ) {
2014-12-12 15:19:41 +08:00
ce = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-12-14 06:06:14 +08:00
ce = zend_fetch_class_by_name ( Z_STR_P ( EX_CONSTANT ( opline - > op2 ) ) , EX_CONSTANT ( opline - > op2 ) + 1 , 0 ) ;
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-08-26 01:24:55 +08:00
zend_string_release ( name ) ;
2012-02-25 21:56:59 +08:00
}
FREE_OP1 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-12-12 15:19:41 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) , 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 ) ) ;
2015-01-13 14:33:15 +08:00
if ( OP1_TYPE = = IS_CONST & &
( retval = CACHED_POLYMORPHIC_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) , ce ) ) ! = NULL ) {
/* check if static properties were destoyed */
if ( UNEXPECTED ( CE_STATIC_MEMBERS ( ce ) = = NULL ) ) {
zend_error_noreturn ( E_ERROR , " Access to undeclared static property: %s::$%s " , ce - > name - > val , name - > val ) ;
}
ZEND_VM_C_GOTO ( fetch_var_return ) ;
}
}
retval = zend_std_get_static_property ( ce , name , 0 ) ;
if ( OP1_TYPE = = IS_CONST & & retval ) {
CACHE_POLYMORPHIC_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) , ce , retval ) ;
2010-05-06 18:27:35 +08:00
}
2015-01-13 14:33:15 +08:00
2009-09-21 21:01:17 +08:00
FREE_OP1 ( ) ;
2004-10-23 05:42:14 +08:00
} else {
2014-12-14 06:06:14 +08:00
target_symbol_table = zend_get_target_symbol_table ( execute_data , opline - > extended_value & ZEND_FETCH_TYPE_MASK ) ;
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-09-16 13:15:47 +08:00
retval = & EG ( uninitialized_zval ) ;
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 :
2014-09-16 13:15:47 +08:00
retval = & EG ( uninitialized_zval ) ;
2014-03-26 22:07:31 +08:00
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 ) ) {
2014-12-14 06:06:14 +08:00
zval_update_constant ( retval , 1 ) ;
2014-06-17 03:32:58 +08:00
}
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-08-26 01:24:55 +08:00
zend_string_release ( name ) ;
2004-10-23 05:42:14 +08:00
}
2014-02-21 21:39:02 +08:00
2015-01-13 14:33:15 +08:00
ZEND_VM_C_LABEL ( fetch_var_return ) :
2014-04-08 04:38:54 +08:00
ZEND_ASSERT ( retval ! = NULL ) ;
if ( type = = BP_VAR_R | | type = = BP_VAR_IS ) {
2014-08-06 03:48:27 +08:00
if ( /*type == BP_VAR_R &&*/ Z_ISREF_P ( retval ) & & Z_REFCOUNT_P ( retval ) = = 1 ) {
ZVAL_UNREF ( retval ) ;
}
2014-04-08 04:38:54 +08:00
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , retval ) ;
} else {
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 ( ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 80 , ZEND_FETCH_R , CONST | TMPVAR | 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 ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 83 , ZEND_FETCH_W , CONST | TMPVAR | 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 ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 86 , ZEND_FETCH_RW , CONST | TMPVAR | 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 ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 92 , ZEND_FETCH_FUNC_ARG , CONST | TMPVAR | CV , UNUSED | CONST | VAR )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2014-12-14 06:06:14 +08:00
if ( zend_is_by_ref_func_arg_fetch ( opline , EX ( call ) ) ) {
2014-04-08 04:38:54 +08:00
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
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 95 , ZEND_FETCH_UNSET , CONST | TMPVAR | 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 ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 89 , ZEND_FETCH_IS , CONST | TMPVAR | 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 ) ;
}
2014-12-08 23:11:14 +08:00
ZEND_VM_HANDLER ( 81 , ZEND_FETCH_DIM_R , CONST | TMPVAR | CV , CONST | TMPVAR | 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 ( ) ;
2014-12-08 23:11:14 +08:00
container = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-12-14 06:06:14 +08:00
zend_fetch_dimension_address_read_R ( EX_VAR ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR ( BP_VAR_R ) , OP2_TYPE ) ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2014-10-05 17:02:58 +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 ( ) ;
}
2014-12-05 18:45:03 +08:00
ZEND_VM_HANDLER ( 84 , ZEND_FETCH_DIM_W , VAR | CV , CONST | TMPVAR | 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 ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-12-09 06:09:44 +08:00
container = GET_OP1_ZVAL_PTR_PTR_UNDEF ( BP_VAR_W ) ;
2010-04-20 19:16:39 +08:00
2014-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use string offset as an array " ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2008-01-24 01:55:55 +08:00
}
2014-12-14 06:06:14 +08:00
zend_fetch_dimension_address_W ( EX_VAR ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR ( BP_VAR_R ) , OP2_TYPE ) ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2014-11-18 14:05:48 +08:00
if ( OP1_TYPE = = IS_VAR & & READY_TO_DESTROY ( free_op1 ) ) {
2014-03-04 21:23:23 +08:00
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 ( ) ;
}
2014-12-05 18:45:03 +08:00
ZEND_VM_HANDLER ( 87 , ZEND_FETCH_DIM_RW , VAR | CV , CONST | TMPVAR | 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-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use string offset as an array " ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2008-01-24 01:55:55 +08:00
}
2014-12-14 06:06:14 +08:00
zend_fetch_dimension_address_RW ( EX_VAR ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR ( BP_VAR_R ) , OP2_TYPE ) ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2014-11-18 14:05:48 +08:00
if ( OP1_TYPE = = IS_VAR & & READY_TO_DESTROY ( free_op1 ) ) {
2014-03-04 21:23:23 +08:00
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 ( ) ;
}
2014-12-08 23:11:14 +08:00
ZEND_VM_HANDLER ( 90 , ZEND_FETCH_DIM_IS , CONST | TMPVAR | CV , CONST | TMPVAR | 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 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-12-08 23:11:14 +08:00
container = GET_OP1_ZVAL_PTR ( BP_VAR_IS ) ;
2014-12-14 06:06:14 +08:00
zend_fetch_dimension_address_read_IS ( EX_VAR ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR ( BP_VAR_R ) , OP2_TYPE ) ;
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 ( ) ;
}
2014-12-05 18:45:03 +08:00
ZEND_VM_HANDLER ( 93 , ZEND_FETCH_DIM_FUNC_ARG , CONST | TMP | VAR | CV , CONST | TMPVAR | 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 ( ) ;
2014-12-14 06:06:14 +08:00
if ( zend_is_by_ref_func_arg_fetch ( opline , EX ( call ) ) ) {
2014-06-01 02:15:55 +08:00
if ( OP1_TYPE = = IS_CONST | | OP1_TYPE = = IS_TMP_VAR ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use temporary expression in write context " ) ;
FREE_UNFETCHED_OP2 ( ) ;
FREE_UNFETCHED_OP1 ( ) ;
HANDLE_EXCEPTION ( ) ;
2014-06-01 02:15:55 +08:00
}
2014-12-09 06:09:44 +08:00
container = GET_OP1_ZVAL_PTR_PTR_UNDEF ( BP_VAR_W ) ;
2010-04-20 19:16:39 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use string offset as an array " ) ;
FREE_UNFETCHED_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2008-01-24 01:55:55 +08:00
}
2014-12-14 06:06:14 +08:00
zend_fetch_dimension_address_W ( EX_VAR ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR ( BP_VAR_R ) , OP2_TYPE ) ;
2014-11-18 14:05:48 +08:00
if ( OP1_TYPE = = IS_VAR & & READY_TO_DESTROY ( free_op1 ) ) {
2014-03-04 21:23:23 +08:00
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 ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use [] for reading " ) ;
FREE_UNFETCHED_OP2 ( ) ;
FREE_UNFETCHED_OP1 ( ) ;
HANDLE_EXCEPTION ( ) ;
2007-11-06 22:11:59 +08:00
}
2014-12-08 23:11:14 +08:00
container = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-12-14 06:06:14 +08:00
zend_fetch_dimension_address_read_R ( EX_VAR ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR ( BP_VAR_R ) , OP2_TYPE ) ;
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 ( ) ;
}
2014-12-05 18:45:03 +08:00
ZEND_VM_HANDLER ( 96 , ZEND_FETCH_DIM_UNSET , VAR | CV , CONST | TMPVAR | 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-04 16:27:50 +08:00
container = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_UNSET ) ;
2004-10-23 05:42:14 +08:00
2014-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use string offset as an array " ) ;
FREE_UNFETCHED_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2008-01-24 01:55:55 +08:00
}
2014-12-14 06:06:14 +08:00
zend_fetch_dimension_address_UNSET ( EX_VAR ( opline - > result . var ) , container , GET_OP2_ZVAL_PTR ( BP_VAR_R ) , OP2_TYPE ) ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2014-11-18 14:05:48 +08:00
if ( OP1_TYPE = = IS_VAR & & READY_TO_DESTROY ( free_op1 ) ) {
2014-03-04 21:23:23 +08:00
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
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 82 , ZEND_FETCH_OBJ_R , CONST | TMP | VAR | UNUSED | CV , CONST | TMPVAR | 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-12-08 23:11:14 +08:00
container = GET_OP1_OBJ_ZVAL_PTR ( BP_VAR_R ) ;
2010-04-20 19:16:39 +08:00
offset = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2014-12-08 23:11:14 +08:00
if ( OP1_TYPE ! = IS_UNUSED & & UNEXPECTED ( Z_TYPE_P ( container ) ! = IS_OBJECT ) ) {
if ( ( OP1_TYPE & ( IS_VAR | IS_CV ) ) & & Z_ISREF_P ( container ) ) {
container = Z_REFVAL_P ( container ) ;
if ( UNEXPECTED ( Z_TYPE_P ( container ) ! = IS_OBJECT ) ) {
ZEND_VM_C_GOTO ( fetch_obj_r_no_object ) ;
}
} else {
ZEND_VM_C_GOTO ( fetch_obj_r_no_object ) ;
}
2015-01-03 17:22:58 +08:00
}
2015-01-13 20:31:42 +08:00
/* here we are sure we are dealing with an object */
do {
zend_object * zobj = Z_OBJ_P ( container ) ;
2007-12-14 22:14:50 +08:00
zval * retval ;
2004-10-23 05:42:14 +08:00
2015-01-13 20:31:42 +08:00
if ( OP2_TYPE = = IS_CONST & &
EXPECTED ( zobj - > ce = = CACHED_PTR ( Z_CACHE_SLOT_P ( offset ) ) ) ) {
2015-02-25 06:52:35 +08:00
uint32_t prop_offset = ( uint32_t ) ( intptr_t ) CACHED_PTR ( Z_CACHE_SLOT_P ( offset ) + sizeof ( void * ) ) ;
2015-01-13 20:31:42 +08:00
2015-02-26 04:20:47 +08:00
if ( EXPECTED ( prop_offset ! = ( uint32_t ) ZEND_DYNAMIC_PROPERTY_OFFSET ) ) {
2015-01-13 20:31:42 +08:00
retval = OBJ_PROP ( zobj , prop_offset ) ;
if ( EXPECTED ( Z_TYPE_P ( retval ) ! = IS_UNDEF ) ) {
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , retval ) ;
break ;
}
} else if ( EXPECTED ( zobj - > properties ! = NULL ) ) {
retval = zend_hash_find ( zobj - > properties , Z_STR_P ( offset ) ) ;
if ( EXPECTED ( retval ) ) {
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , retval ) ;
break ;
2014-11-06 19:50:03 +08:00
}
}
2015-01-13 20:31:42 +08:00
}
2004-10-23 05:42:14 +08:00
2015-01-13 20:31:42 +08:00
if ( UNEXPECTED ( zobj - > handlers - > read_property = = NULL ) ) {
ZEND_VM_C_LABEL ( fetch_obj_r_no_object ) :
zend_error ( E_NOTICE , " Trying to get property of non-object " ) ;
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
} else {
2015-02-25 06:52:35 +08:00
retval = zobj - > handlers - > read_property ( container , offset , BP_VAR_R , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( offset ) ) : NULL ) , EX_VAR ( opline - > result . var ) ) ;
2014-11-06 19:50:03 +08:00
if ( retval ! = EX_VAR ( opline - > result . var ) ) {
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , retval ) ;
}
2015-01-13 20:31:42 +08:00
}
} while ( 0 ) ;
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 ( ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 85 , ZEND_FETCH_OBJ_W , VAR | UNUSED | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
zval * 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-12-09 06:09:44 +08:00
container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF ( BP_VAR_W ) ;
2014-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use string offset as an object " ) ;
FREE_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2008-01-24 01:55:55 +08:00
}
2010-04-20 19:16:39 +08:00
2015-02-25 06:52:35 +08:00
zend_fetch_property_address ( EX_VAR ( opline - > result . var ) , container , OP1_TYPE , property , OP2_TYPE , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( property ) ) : NULL ) , BP_VAR_W ) ;
2014-04-16 01:56:30 +08:00
FREE_OP2 ( ) ;
2014-11-18 14:05:48 +08:00
if ( OP1_TYPE = = IS_VAR & & READY_TO_DESTROY ( free_op1 ) ) {
2014-03-04 21:23:23 +08:00
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 ( ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 88 , ZEND_FETCH_OBJ_RW , VAR | UNUSED | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 , free_op2 ;
2010-04-20 19:16:39 +08:00
zval * 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-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use string offset as an object " ) ;
FREE_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2008-01-24 01:55:55 +08:00
}
2015-02-25 06:52:35 +08:00
zend_fetch_property_address ( EX_VAR ( opline - > result . var ) , container , OP1_TYPE , property , OP2_TYPE , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( property ) ) : NULL ) , BP_VAR_RW ) ;
2014-04-16 01:56:30 +08:00
FREE_OP2 ( ) ;
2014-11-18 14:05:48 +08:00
if ( OP1_TYPE = = IS_VAR & & READY_TO_DESTROY ( free_op1 ) ) {
2014-03-04 21:23:23 +08:00
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 ( ) ;
}
2014-12-08 23:11:14 +08:00
ZEND_VM_HANDLER ( 91 , ZEND_FETCH_OBJ_IS , CONST | TMPVAR | UNUSED | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
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-12-08 23:11:14 +08:00
container = GET_OP1_OBJ_ZVAL_PTR ( BP_VAR_IS ) ;
2010-04-20 19:16:39 +08:00
offset = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2014-12-08 23:11:14 +08:00
if ( OP1_TYPE ! = IS_UNUSED & & UNEXPECTED ( Z_TYPE_P ( container ) ! = IS_OBJECT ) ) {
if ( ( OP1_TYPE & ( IS_VAR | IS_CV ) ) & & Z_ISREF_P ( container ) ) {
container = Z_REFVAL_P ( container ) ;
if ( UNEXPECTED ( Z_TYPE_P ( container ) ! = IS_OBJECT ) ) {
ZEND_VM_C_GOTO ( fetch_obj_is_no_object ) ;
}
} else {
ZEND_VM_C_GOTO ( fetch_obj_is_no_object ) ;
}
2015-01-03 17:22:58 +08:00
}
2015-01-13 20:31:42 +08:00
/* here we are sure we are dealing with an object */
do {
zend_object * zobj = Z_OBJ_P ( container ) ;
2010-04-20 19:16:39 +08:00
zval * retval ;
2015-01-13 20:31:42 +08:00
if ( OP2_TYPE = = IS_CONST & &
EXPECTED ( zobj - > ce = = CACHED_PTR ( Z_CACHE_SLOT_P ( offset ) ) ) ) {
2015-02-25 06:52:35 +08:00
uint32_t prop_offset = ( uint32_t ) ( intptr_t ) CACHED_PTR ( Z_CACHE_SLOT_P ( offset ) + sizeof ( void * ) ) ;
2015-01-13 20:31:42 +08:00
2015-02-26 04:20:47 +08:00
if ( EXPECTED ( prop_offset ! = ( uint32_t ) ZEND_DYNAMIC_PROPERTY_OFFSET ) ) {
2015-01-13 20:31:42 +08:00
retval = OBJ_PROP ( zobj , prop_offset ) ;
if ( EXPECTED ( Z_TYPE_P ( retval ) ! = IS_UNDEF ) ) {
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , retval ) ;
break ;
}
} else if ( EXPECTED ( zobj - > properties ! = NULL ) ) {
retval = zend_hash_find ( zobj - > properties , Z_STR_P ( offset ) ) ;
if ( EXPECTED ( retval ) ) {
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , retval ) ;
break ;
2014-11-06 19:50:03 +08:00
}
}
2015-01-13 20:31:42 +08:00
}
2010-04-20 19:16:39 +08:00
2015-01-13 20:31:42 +08:00
if ( UNEXPECTED ( zobj - > handlers - > read_property = = NULL ) ) {
ZEND_VM_C_LABEL ( fetch_obj_is_no_object ) :
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
} else {
2015-02-25 06:52:35 +08:00
retval = zobj - > handlers - > read_property ( container , offset , BP_VAR_IS , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( offset ) ) : NULL ) , EX_VAR ( opline - > result . var ) ) ;
2014-11-06 19:50:03 +08:00
if ( retval ! = EX_VAR ( opline - > result . var ) ) {
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , retval ) ;
}
2015-01-13 20:31:42 +08:00
}
} while ( 0 ) ;
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
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 94 , ZEND_FETCH_OBJ_FUNC_ARG , CONST | TMP | VAR | UNUSED | CV , CONST | TMPVAR | 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
2014-12-14 06:06:14 +08:00
if ( zend_is_by_ref_func_arg_fetch ( opline , EX ( call ) ) ) {
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-12-09 06:09:44 +08:00
container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF ( BP_VAR_W ) ;
2004-10-23 05:42:14 +08:00
2015-03-09 20:57:15 +08:00
if ( OP1_TYPE = = IS_CONST | | OP1_TYPE = = IS_TMP_VAR ) {
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use temporary expression in write context " ) ;
FREE_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
}
2014-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use string offset as an object " ) ;
FREE_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2008-01-24 01:55:55 +08:00
}
2015-02-25 06:52:35 +08:00
zend_fetch_property_address ( EX_VAR ( opline - > result . var ) , container , OP1_TYPE , property , OP2_TYPE , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( property ) ) : NULL ) , BP_VAR_W ) ;
2014-04-16 01:56:30 +08:00
FREE_OP2 ( ) ;
2014-11-18 14:05:48 +08:00
if ( OP1_TYPE = = IS_VAR & & READY_TO_DESTROY ( free_op1 ) ) {
2014-03-04 21:23:23 +08:00
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 {
2014-09-24 03:26:39 +08:00
ZEND_VM_DISPATCH_TO_HANDLER ( ZEND_FETCH_OBJ_R ) ;
2004-10-23 05:42:14 +08:00
}
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 97 , ZEND_FETCH_OBJ_UNSET , VAR | UNUSED | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
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-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use string offset as an object " ) ;
FREE_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2008-01-24 01:55:55 +08:00
}
2015-02-25 06:52:35 +08:00
zend_fetch_property_address ( EX_VAR ( opline - > result . var ) , container , OP1_TYPE , property , OP2_TYPE , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( property ) ) : NULL ) , BP_VAR_UNSET ) ;
2014-04-16 01:56:30 +08:00
FREE_OP2 ( ) ;
2014-11-18 14:05:48 +08:00
if ( OP1_TYPE = = IS_VAR & & READY_TO_DESTROY ( free_op1 ) ) {
2014-03-04 21:23:23 +08:00
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 ( ) ;
}
2014-12-08 23:11:14 +08:00
ZEND_VM_HANDLER ( 98 , ZEND_FETCH_LIST , CONST | TMPVAR | CV , 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 ( ) ;
2014-12-08 23:11:14 +08:00
container = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2014-12-08 23:11:14 +08:00
ZEND_VM_C_LABEL ( try_fetch_list ) :
2014-10-05 17:02:58 +08:00
if ( EXPECTED ( Z_TYPE_P ( container ) = = IS_ARRAY ) ) {
2015-02-26 22:53:03 +08:00
zval * value = zend_fetch_dimension_address_inner ( Z_ARRVAL_P ( container ) , EX_CONSTANT ( opline - > op2 ) , OP2_TYPE , BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2014-02-10 14:04:30 +08:00
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , value ) ;
2014-10-05 17:02:58 +08:00
} else if ( UNEXPECTED ( Z_TYPE_P ( container ) = = IS_OBJECT ) & &
EXPECTED ( Z_OBJ_HT_P ( container ) - > read_dimension ) ) {
zval * result = EX_VAR ( opline - > result . var ) ;
2015-02-26 22:53:03 +08:00
zval * retval = Z_OBJ_HT_P ( container ) - > read_dimension ( container , EX_CONSTANT ( opline - > op2 ) , BP_VAR_R , result ) ;
2014-10-05 17:02:58 +08:00
if ( retval ) {
if ( result ! = retval ) {
ZVAL_COPY ( result , retval ) ;
}
} else {
ZVAL_NULL ( result ) ;
}
2014-12-08 23:11:14 +08:00
} else if ( Z_TYPE_P ( container ) = = IS_REFERENCE ) {
container = Z_REFVAL_P ( container ) ;
ZEND_VM_C_GOTO ( try_fetch_list ) ;
2014-10-05 17:02:58 +08:00
} else {
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
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-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 136 , ZEND_ASSIGN_OBJ , VAR | UNUSED | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
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-12-09 05:10:23 +08:00
object = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF ( 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-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( object = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use string offset as an array " ) ;
FREE_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2008-01-24 01:55:55 +08:00
}
2015-02-25 06:52:35 +08:00
zend_assign_to_object ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ? EX_VAR ( opline - > result . var ) : NULL , object , OP1_TYPE , property_name , OP2_TYPE , ( opline + 1 ) - > op1_type , ( opline + 1 ) - > op1 , execute_data , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( property_name ) ) : NULL ) ) ;
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 ( ) ;
}
2014-12-05 18:45:03 +08:00
ZEND_VM_HANDLER ( 147 , ZEND_ASSIGN_DIM , VAR | CV , CONST | TMPVAR | 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 ;
2014-12-09 05:10:23 +08:00
zend_free_op free_op2 , free_op_data1 ;
zval * value ;
zval * variable_ptr ;
zval * dim ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-12-09 05:10:23 +08:00
object_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF ( BP_VAR_W ) ;
2010-04-20 19:16:39 +08:00
2014-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( object_ptr = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use string offset as an array " ) ;
FREE_UNFETCHED_OP ( ( opline + 1 ) - > op1_type , ( opline + 1 ) - > op1 . var ) ;
FREE_UNFETCHED_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
2007-12-14 22:14:50 +08:00
2014-12-09 05:10:23 +08:00
ZEND_VM_C_LABEL ( try_assign_dim ) :
if ( EXPECTED ( Z_TYPE_P ( object_ptr ) = = IS_ARRAY ) ) {
ZEND_VM_C_LABEL ( try_assign_dim_array ) :
2015-02-26 07:49:19 +08:00
if ( OP2_TYPE = = IS_UNUSED ) {
SEPARATE_ARRAY ( object_ptr ) ;
variable_ptr = zend_hash_next_index_insert ( Z_ARRVAL_P ( object_ptr ) , & EG ( uninitialized_zval ) ) ;
if ( UNEXPECTED ( variable_ptr = = NULL ) ) {
zend_error ( E_WARNING , " Cannot add element to the array as the next element is already occupied " ) ;
variable_ptr = & EG ( error_zval ) ;
}
} else {
dim = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
SEPARATE_ARRAY ( object_ptr ) ;
variable_ptr = zend_fetch_dimension_address_inner ( Z_ARRVAL_P ( object_ptr ) , dim , OP2_TYPE , BP_VAR_W ) ;
FREE_OP2 ( ) ;
}
2014-12-09 08:03:38 +08:00
value = get_zval_ptr_deref ( ( opline + 1 ) - > op1_type , ( opline + 1 ) - > op1 , execute_data , & free_op_data1 , BP_VAR_R ) ;
2014-12-09 05:10:23 +08:00
if ( UNEXPECTED ( variable_ptr = = & EG ( error_zval ) ) ) {
2014-09-23 21:21:29 +08:00
FREE_OP ( free_op_data1 ) ;
2014-12-09 22:07:12 +08:00
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
2014-12-09 05:10:23 +08:00
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
}
2007-12-14 22:14:50 +08:00
} else {
2014-12-14 06:06:14 +08:00
value = zend_assign_to_variable ( variable_ptr , value , ( opline + 1 ) - > op1_type ) ;
2014-12-09 05:10:23 +08:00
if ( ( opline + 1 ) - > op1_type = = IS_VAR ) {
2014-09-23 21:21:29 +08:00
FREE_OP ( free_op_data1 ) ;
2014-12-09 05:10:23 +08:00
}
2014-12-09 22:07:12 +08:00
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
2014-12-09 05:10:23 +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
}
2014-12-09 05:10:23 +08:00
} else if ( EXPECTED ( Z_TYPE_P ( object_ptr ) = = IS_OBJECT ) ) {
zend_free_op free_op2 ;
zval * property_name = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2014-12-14 06:06:14 +08:00
zend_assign_to_object_dim ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ? EX_VAR ( opline - > result . var ) : NULL , object_ptr , property_name , ( opline + 1 ) - > op1_type , ( opline + 1 ) - > op1 , execute_data ) ;
2014-12-09 05:10:23 +08:00
FREE_OP2 ( ) ;
2015-02-26 07:49:19 +08:00
} else if ( EXPECTED ( Z_TYPE_P ( object_ptr ) = = IS_STRING ) ) {
if ( EXPECTED ( Z_STRLEN_P ( object_ptr ) ! = 0 ) ) {
zend_long offset ;
2014-12-09 05:10:23 +08:00
2015-02-26 07:49:19 +08:00
dim = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
offset = zend_fetch_string_offset ( object_ptr , dim , BP_VAR_W ) ;
FREE_OP2 ( ) ;
value = get_zval_ptr_deref ( ( opline + 1 ) - > op1_type , ( opline + 1 ) - > op1 , execute_data , & free_op_data1 , BP_VAR_R ) ;
zend_assign_to_string_offset ( object_ptr , offset , value , ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ? EX_VAR ( opline - > result . var ) : NULL ) ) ;
FREE_OP ( free_op_data1 ) ;
} else {
zval_ptr_dtor_nogc ( object_ptr ) ;
ZEND_VM_C_LABEL ( assign_dim_convert_to_array ) :
ZVAL_NEW_ARR ( object_ptr ) ;
zend_hash_init ( Z_ARRVAL_P ( object_ptr ) , 8 , NULL , ZVAL_PTR_DTOR , 0 ) ;
ZEND_VM_C_GOTO ( try_assign_dim_array ) ;
}
2014-12-09 05:10:23 +08:00
} else if ( EXPECTED ( Z_ISREF_P ( object_ptr ) ) ) {
object_ptr = Z_REFVAL_P ( object_ptr ) ;
ZEND_VM_C_GOTO ( try_assign_dim ) ;
2015-02-26 07:49:19 +08:00
} else if ( EXPECTED ( Z_TYPE_P ( object_ptr ) < = IS_FALSE ) ) {
if ( UNEXPECTED ( object_ptr = = & EG ( error_zval ) ) ) {
ZEND_VM_C_GOTO ( assign_dim_clean ) ;
}
ZEND_VM_C_GOTO ( assign_dim_convert_to_array ) ;
2014-12-09 05:10:23 +08:00
} else {
2015-02-26 07:49:19 +08:00
zend_error ( E_WARNING , " Cannot use a scalar value as an array " ) ;
ZEND_VM_C_LABEL ( assign_dim_clean ) :
dim = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
FREE_OP2 ( ) ;
value = get_zval_ptr ( ( opline + 1 ) - > op1_type , ( opline + 1 ) - > op1 , execute_data , & free_op_data1 , BP_VAR_R ) ;
FREE_OP ( free_op_data1 ) ;
if ( UNEXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
}
2004-10-23 05:42:14 +08:00
}
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 ( ) ;
2014-09-11 21:00:06 +08:00
value = GET_OP2_ZVAL_PTR_DEREF ( 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-09-07 06:54:47 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( variable_ptr = = & EG ( error_zval ) ) ) {
2014-09-22 16:47:10 +08:00
if ( OP2_TYPE = = IS_TMP_VAR ) {
2014-09-23 21:21:29 +08:00
FREE_OP2 ( ) ;
2010-04-20 19:16:39 +08:00
}
2014-12-09 22:07:12 +08:00
if ( UNEXPECTED ( 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 {
2014-12-14 06:06:14 +08:00
value = zend_assign_to_variable ( variable_ptr , value , OP2_TYPE ) ;
2014-12-09 22:07:12 +08:00
if ( UNEXPECTED ( 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
2014-10-23 01:45:02 +08:00
if ( OP2_TYPE = = IS_VAR & & UNEXPECTED ( value_ptr = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot create references to/from string offsets nor overloaded objects " ) ;
FREE_OP2_VAR_PTR ( ) ;
FREE_UNFETCHED_OP1 ( ) ;
HANDLE_EXCEPTION ( ) ;
2014-10-23 01:45:02 +08:00
}
2005-05-06 01:37:25 +08:00
if ( OP2_TYPE = = IS_VAR & &
2014-10-23 01:45:02 +08:00
( value_ptr = = & EG ( uninitialized_zval ) | |
( opline - > extended_value = = ZEND_RETURNS_FUNCTION & &
! ( Z_VAR_FLAGS_P ( value_ptr ) & IS_VAR_RET_REF ) ) ) ) {
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 ) ;
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-10-23 01:45:02 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( variable_ptr = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot create references to/from string offsets nor overloaded objects " ) ;
FREE_OP2_VAR_PTR ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2014-10-23 01:45:02 +08:00
}
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 ) ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot assign by reference to overloaded object " ) ;
FREE_OP2_VAR_PTR ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2014-03-04 20:32:40 +08:00
}
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 {
2014-12-14 06:06:14 +08:00
zend_assign_to_variable_reference ( variable_ptr , value_ptr ) ;
2014-04-03 20:53:30 +08:00
}
2004-10-23 05:42:14 +08:00
2014-12-09 22:07:12 +08:00
if ( UNEXPECTED ( 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
{
2015-03-03 21:51:27 +08:00
zend_execute_data * old_execute_data ;
2014-11-28 15:33:03 +08:00
zend_call_kind call_kind = EX_CALL_KIND ( ) ;
2012-12-21 08:56:37 +08:00
2014-11-28 15:33:03 +08:00
if ( call_kind = = ZEND_CALL_NESTED_FUNCTION ) {
2014-10-03 23:32:46 +08:00
zend_object * object ;
2014-12-14 06:06:14 +08:00
i_free_compiled_variables ( execute_data ) ;
2014-04-18 17:46:36 +08:00
if ( UNEXPECTED ( EX ( symbol_table ) ! = NULL ) ) {
2014-12-14 06:06:14 +08:00
zend_clean_and_cache_symbol_table ( EX ( symbol_table ) ) ;
2014-04-18 17:46:36 +08:00
}
2014-12-14 06:06:14 +08:00
zend_vm_stack_free_extra_args ( execute_data ) ;
2015-03-03 21:51:27 +08:00
old_execute_data = execute_data ;
execute_data = EG ( current_execute_data ) = EX ( prev_execute_data ) ;
2015-03-11 04:04:41 +08:00
if ( UNEXPECTED ( old_execute_data - > func - > op_array . fn_flags & ZEND_ACC_CLOSURE ) ) {
2015-03-03 21:51:27 +08:00
OBJ_RELEASE ( ( zend_object * ) old_execute_data - > func - > op_array . prototype ) ;
2014-07-10 22:36:11 +08:00
}
2015-03-03 21:51:27 +08:00
object = Z_OBJ ( old_execute_data - > This ) ;
zend_vm_stack_free_call_frame ( old_execute_data ) ;
2014-03-26 22:07:31 +08:00
2014-10-03 23:32:46 +08:00
if ( object ) {
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-10-03 23:32:46 +08:00
GC_REFCOUNT ( object ) - - ;
2014-04-18 17:46:36 +08:00
}
2014-10-03 23:32:46 +08:00
if ( GC_REFCOUNT ( object ) = = 1 ) {
2014-12-14 06:06:14 +08:00
zend_object_store_ctor_failed ( object ) ;
2014-04-18 17:46:36 +08:00
}
2012-08-22 18:32:03 +08:00
}
2014-10-03 23:32:46 +08:00
OBJ_RELEASE ( object ) ;
2014-04-18 17:46:36 +08:00
}
2014-11-28 15:21:18 +08:00
EG ( scope ) = EX ( func ) - > op_array . scope ;
2004-10-23 05:42:14 +08:00
2014-04-18 17:46:36 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2015-03-13 08:28:21 +08:00
const zend_op * old_opline = EX ( opline ) ;
2014-12-14 06:06:14 +08:00
zend_throw_exception_internal ( NULL ) ;
2015-03-13 08:28:21 +08:00
if ( RETURN_VALUE_USED ( old_opline ) ) {
zval_ptr_dtor ( EX_VAR ( old_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 ( ) ;
2014-11-28 15:33:03 +08:00
} else if ( call_kind = = ZEND_CALL_NESTED_CODE ) {
2014-04-18 17:46:36 +08:00
zend_detach_symbol_table ( execute_data ) ;
2014-12-14 06:06:14 +08:00
destroy_op_array ( & EX ( func ) - > op_array ) ;
2014-08-28 00:49:56 +08:00
efree_size ( EX ( func ) , sizeof ( zend_op_array ) ) ;
2015-03-03 21:51:27 +08:00
old_execute_data = execute_data ;
execute_data = EG ( current_execute_data ) = EX ( prev_execute_data ) ;
zend_vm_stack_free_call_frame ( old_execute_data ) ;
2004-10-23 05:42:14 +08:00
2014-04-18 17:46:36 +08:00
zend_attach_symbol_table ( execute_data ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2014-12-14 06:06:14 +08:00
zend_throw_exception_internal ( NULL ) ;
2014-04-18 17:46:36 +08:00
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 {
2014-11-28 15:33:03 +08:00
if ( call_kind = = ZEND_CALL_TOP_FUNCTION ) {
2014-12-14 06:06:14 +08:00
i_free_compiled_variables ( execute_data ) ;
2014-07-04 22:03:45 +08:00
if ( UNEXPECTED ( EX ( symbol_table ) ! = NULL ) ) {
2014-12-14 06:06:14 +08:00
zend_clean_and_cache_symbol_table ( EX ( symbol_table ) ) ;
2014-07-04 22:03:45 +08:00
}
2014-12-14 06:06:14 +08:00
zend_vm_stack_free_extra_args ( execute_data ) ;
2014-07-10 22:36:11 +08:00
EG ( current_execute_data ) = EX ( prev_execute_data ) ;
2015-03-11 04:04:41 +08:00
if ( EX ( func ) - > op_array . fn_flags & ZEND_ACC_CLOSURE ) {
2014-07-10 22:36:11 +08:00
OBJ_RELEASE ( ( zend_object * ) EX ( func ) - > op_array . prototype ) ;
2014-07-08 17:24:23 +08:00
}
2014-11-28 15:33:03 +08:00
} else /* if (call_kind == ZEND_CALL_TOP_CODE) */ {
2014-04-18 17:46:36 +08:00
zend_array * symbol_table = EX ( symbol_table ) ;
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
}
2014-07-10 22:36:11 +08:00
EG ( current_execute_data ) = EX ( prev_execute_data ) ;
2009-03-18 22:17:15 +08:00
}
2014-12-14 06:06:14 +08:00
zend_vm_stack_free_call_frame ( execute_data ) ;
2015-01-03 17:22:58 +08:00
2014-04-18 17:46:36 +08:00
ZEND_VM_RETURN ( ) ;
2015-01-03 17:22:58 +08:00
}
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
2014-12-12 15:19:41 +08:00
ZEND_VM_SET_OPCODE ( OP_JMP_ADDR ( opline , opline - > op1 ) ) ;
2012-11-22 19:17:05 +08:00
ZEND_VM_CONTINUE ( ) ;
2004-10-23 05:42:14 +08:00
}
2014-12-05 22:04:15 +08:00
ZEND_VM_HANDLER ( 43 , ZEND_JMPZ , CONST | TMPVAR | 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-12-05 22:04:15 +08:00
val = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2011-03-16 13:25:02 +08:00
2015-01-03 17:22:58 +08:00
if ( Z_TYPE_P ( val ) = = IS_TRUE ) {
2015-03-17 00:48:29 +08:00
ZEND_VM_SET_NEXT_OPCODE ( opline + 1 ) ;
2014-12-05 22:04:15 +08:00
ZEND_VM_CONTINUE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( val ) < = IS_TRUE ) ) {
if ( OP1_TYPE = = IS_CV ) {
2014-12-12 15:19:41 +08:00
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2015-01-03 17:22:58 +08:00
} else {
2014-12-12 15:19:41 +08:00
ZEND_VM_SET_OPCODE ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2014-05-01 05:24:38 +08:00
ZEND_VM_CONTINUE ( ) ;
2004-10-23 05:42:14 +08:00
}
}
2014-12-14 06:06:14 +08:00
if ( i_zend_is_true ( val ) ) {
2014-05-01 05:24:38 +08:00
opline + + ;
} else {
2014-12-12 15:19:41 +08:00
opline = OP_JMP_ADDR ( opline , opline - > op2 ) ;
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
}
2014-12-05 22:04:15 +08:00
ZEND_VM_HANDLER ( 44 , ZEND_JMPNZ , CONST | TMPVAR | 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-12-05 22:04:15 +08:00
val = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2014-12-05 22:04:15 +08:00
if ( Z_TYPE_P ( val ) = = IS_TRUE ) {
2014-12-12 15:19:41 +08:00
ZEND_VM_SET_OPCODE ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2014-12-05 22:04:15 +08:00
ZEND_VM_CONTINUE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( val ) < = IS_TRUE ) ) {
if ( OP1_TYPE = = IS_CV ) {
ZEND_VM_NEXT_OPCODE ( ) ;
2015-01-03 17:22:58 +08:00
} else {
2015-03-17 00:48:29 +08:00
ZEND_VM_SET_NEXT_OPCODE ( opline + 1 ) ;
2014-05-01 05:24:38 +08:00
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-12-14 06:06:14 +08:00
if ( i_zend_is_true ( val ) ) {
2014-12-12 15:19:41 +08:00
opline = OP_JMP_ADDR ( opline , opline - > op2 ) ;
2014-05-01 05:24:38 +08:00
} 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
2014-12-05 22:04:15 +08:00
ZEND_VM_HANDLER ( 45 , ZEND_JMPZNZ , CONST | TMPVAR | CV , ANY )
2012-08-22 18:32:03 +08:00
{
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-12-05 22:04:15 +08:00
val = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2014-12-05 22:04:15 +08:00
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 ) ) {
if ( OP1_TYPE = = IS_CV ) {
2014-12-12 15:19:41 +08:00
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2015-01-03 17:22:58 +08:00
} else {
2014-12-12 15:19:41 +08:00
ZEND_VM_SET_OPCODE ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2014-05-01 05:24:38 +08:00
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
2014-12-14 06:06:14 +08:00
if ( i_zend_is_true ( val ) ) {
2014-12-12 15:19:41 +08:00
opline = ZEND_OFFSET_TO_OPLINE ( opline , opline - > extended_value ) ;
2012-08-22 18:32:03 +08:00
} else {
2014-12-12 15:19:41 +08:00
opline = OP_JMP_ADDR ( opline , opline - > op2 ) ;
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
}
2004-10-23 05:42:14 +08:00
2014-12-05 22:04:15 +08:00
ZEND_VM_HANDLER ( 46 , ZEND_JMPZ_EX , CONST | TMPVAR | CV , ANY )
2012-08-22 18:32:03 +08:00
{
USE_OPLINE
zend_free_op free_op1 ;
zval * val ;
2015-01-24 01:35:32 +08:00
int ret ;
2012-08-22 18:32:03 +08:00
SAVE_OPLINE ( ) ;
2014-12-05 22:04:15 +08:00
val = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2012-08-22 18:32:03 +08:00
2014-12-05 22:04:15 +08:00
if ( Z_TYPE_P ( val ) = = IS_TRUE ) {
ZVAL_TRUE ( EX_VAR ( opline - > result . var ) ) ;
2015-03-17 00:48:29 +08:00
ZEND_VM_SET_NEXT_OPCODE ( opline + 1 ) ;
2014-12-05 22:04:15 +08:00
ZEND_VM_CONTINUE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( val ) < = IS_TRUE ) ) {
ZVAL_FALSE ( EX_VAR ( opline - > result . var ) ) ;
if ( OP1_TYPE = = IS_CV ) {
2014-12-12 15:19:41 +08:00
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2015-01-03 17:22:58 +08:00
} else {
2014-12-12 15:19:41 +08:00
ZEND_VM_SET_OPCODE ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2014-05-01 05:24:38 +08:00
ZEND_VM_CONTINUE ( ) ;
2004-10-23 05:42:14 +08:00
}
}
2014-05-01 05:24:38 +08:00
2015-01-24 01:35:32 +08:00
ret = i_zend_is_true ( val ) ;
FREE_OP1 ( ) ;
if ( ret ) {
2014-05-01 05:24:38 +08:00
ZVAL_TRUE ( EX_VAR ( opline - > result . var ) ) ;
opline + + ;
} else {
ZVAL_FALSE ( EX_VAR ( opline - > result . var ) ) ;
2014-12-12 15:19:41 +08:00
opline = OP_JMP_ADDR ( opline , opline - > op2 ) ;
2012-08-22 18:32:03 +08:00
}
2014-05-01 05:24:38 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
ZEND_VM_JMP ( opline ) ;
2004-10-23 05:42:14 +08:00
}
2014-12-05 22:04:15 +08:00
ZEND_VM_HANDLER ( 47 , ZEND_JMPNZ_EX , CONST | TMPVAR | 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 ;
2015-01-24 01:35:32 +08:00
int ret ;
2010-04-20 19:16:39 +08:00
2012-08-22 18:32:03 +08:00
SAVE_OPLINE ( ) ;
2014-12-05 22:04:15 +08:00
val = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2014-12-05 22:04:15 +08:00
if ( Z_TYPE_P ( val ) = = IS_TRUE ) {
ZVAL_TRUE ( EX_VAR ( opline - > result . var ) ) ;
2014-12-12 15:19:41 +08:00
ZEND_VM_SET_OPCODE ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2014-12-05 22:04:15 +08:00
ZEND_VM_CONTINUE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( val ) < = IS_TRUE ) ) {
ZVAL_FALSE ( EX_VAR ( opline - > result . var ) ) ;
if ( OP1_TYPE = = IS_CV ) {
ZEND_VM_NEXT_OPCODE ( ) ;
2015-01-03 17:22:58 +08:00
} else {
2015-03-17 00:48:29 +08:00
ZEND_VM_SET_NEXT_OPCODE ( opline + 1 ) ;
2014-05-01 05:24:38 +08:00
ZEND_VM_CONTINUE ( ) ;
}
}
2015-01-24 01:35:32 +08:00
ret = i_zend_is_true ( val ) ;
FREE_OP1 ( ) ;
if ( ret ) {
2014-05-01 05:24:38 +08:00
ZVAL_TRUE ( EX_VAR ( opline - > result . var ) ) ;
2014-12-12 15:19:41 +08:00
opline = OP_JMP_ADDR ( opline , opline - > op2 ) ;
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
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
2014-12-03 23:02:02 +08:00
ZEND_VM_HANDLER ( 70 , ZEND_FREE , TMPVAR , ANY )
2012-08-22 18:32:03 +08:00
{
USE_OPLINE
2012-01-26 09:28:37 +08:00
2012-08-22 18:32:03 +08:00
SAVE_OPLINE ( ) ;
2014-09-23 21:21:29 +08:00
zval_ptr_dtor_nogc ( 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
2015-02-12 18:57:12 +08:00
ZEND_VM_HANDLER ( 127 , ZEND_FE_FREE , TMPVAR , ANY )
{
zval * var ;
USE_OPLINE
SAVE_OPLINE ( ) ;
var = EX_VAR ( opline - > op1 . var ) ;
if ( Z_TYPE_P ( var ) ! = IS_ARRAY & & Z_FE_ITER_P ( var ) ! = ( uint32_t ) - 1 ) {
zend_hash_iterator_del ( Z_FE_ITER_P ( var ) ) ;
}
zval_ptr_dtor_nogc ( var ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2015-03-25 03:47:21 +08:00
ZEND_VM_HANDLER ( 53 , ZEND_FAST_CONCAT , CONST | TMPVAR | CV , CONST | TMPVAR | CV )
2012-08-22 18:32:03 +08:00
{
USE_OPLINE
2015-03-25 03:47:21 +08:00
zend_free_op free_op1 , free_op2 ;
zval * op1 , * op2 ;
zend_string * op1_str , * op2_str , * str ;
2011-06-07 05:42:05 +08:00
2012-08-22 18:32:03 +08:00
SAVE_OPLINE ( ) ;
2015-03-25 03:47:21 +08:00
op1 = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
op2 = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
if ( OP1_TYPE = = IS_CONST ) {
op1_str = Z_STR_P ( op1 ) ;
} else {
op1_str = zval_get_string ( op1 ) ;
2005-06-16 22:20:00 +08:00
}
2015-03-25 03:47:21 +08:00
if ( OP2_TYPE = = IS_CONST ) {
op2_str = Z_STR_P ( op2 ) ;
} else {
op2_str = zval_get_string ( op2 ) ;
}
str = zend_string_alloc ( op1_str - > len + op2_str - > len , 0 ) ;
memcpy ( str - > val , op1_str - > val , op1_str - > len ) ;
memcpy ( str - > val + op1_str - > len , op2_str - > val , op2_str - > len + 1 ) ;
ZVAL_NEW_STR ( EX_VAR ( opline - > result . var ) , str ) ;
if ( OP1_TYPE ! = IS_CONST ) {
zend_string_release ( op1_str ) ;
}
if ( OP2_TYPE ! = IS_CONST ) {
zend_string_release ( op2_str ) ;
}
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
CHECK_EXCEPTION ( ) ;
2012-08-22 18:32:03 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2015-03-25 03:47:21 +08:00
ZEND_VM_HANDLER ( 54 , ZEND_ROPE_INIT , UNUSED , CONST | TMPVAR | CV )
2007-11-22 17:02:55 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2015-03-25 03:47:21 +08:00
zend_free_op free_op2 ;
zend_string * * rope ;
zval * var ;
2010-04-27 20:23:29 +08:00
2015-03-25 03:47:21 +08:00
/* Compiler allocates the necessary number of zval slots to keep the rope */
rope = ( zend_string * * ) EX_VAR ( opline - > result . var ) ;
if ( OP2_TYPE = = IS_CONST ) {
var = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
rope [ 0 ] = zend_string_copy ( Z_STR_P ( var ) ) ;
} else {
SAVE_OPLINE ( ) ;
var = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
rope [ 0 ] = zval_get_string ( var ) ;
FREE_OP2 ( ) ;
CHECK_EXCEPTION ( ) ;
2007-11-22 17:02:55 +08:00
}
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2015-03-25 03:47:21 +08:00
ZEND_VM_HANDLER ( 55 , ZEND_ROPE_ADD , TMP , CONST | TMPVAR | 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 ;
2015-03-25 03:47:21 +08:00
zend_string * * rope ;
2010-04-20 19:16:39 +08:00
zval * var ;
2012-08-13 23:17:18 +08:00
2015-03-25 03:47:21 +08:00
/* op1 and result are the same */
rope = ( zend_string * * ) EX_VAR ( opline - > op1 . var ) ;
if ( OP2_TYPE = = IS_CONST ) {
var = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
rope [ opline - > extended_value ] = zend_string_copy ( Z_STR_P ( var ) ) ;
} else {
SAVE_OPLINE ( ) ;
var = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
rope [ opline - > extended_value ] = zval_get_string ( var ) ;
FREE_OP2 ( ) ;
CHECK_EXCEPTION ( ) ;
2012-08-13 23:17:18 +08:00
}
2015-03-25 03:47:21 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2012-08-13 23:17:18 +08:00
2015-03-25 03:47:21 +08:00
ZEND_VM_HANDLER ( 56 , ZEND_ROPE_END , TMP , CONST | TMPVAR | CV )
{
USE_OPLINE
zend_free_op free_op2 ;
zend_string * * rope ;
zval * var , * ret ;
uint32_t i ;
size_t len = 0 ;
char * target ;
rope = ( zend_string * * ) EX_VAR ( opline - > op1 . var ) ;
if ( OP2_TYPE = = IS_CONST ) {
var = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
rope [ opline - > extended_value ] = zend_string_copy ( Z_STR_P ( var ) ) ;
} else {
SAVE_OPLINE ( ) ;
var = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
rope [ opline - > extended_value ] = zval_get_string ( var ) ;
FREE_OP2 ( ) ;
CHECK_EXCEPTION ( ) ;
2008-06-11 21:18:41 +08:00
}
2015-03-25 03:47:21 +08:00
for ( i = 0 ; i < = opline - > extended_value ; i + + ) {
len + = rope [ i ] - > len ;
2011-04-20 20:59:18 +08:00
}
2015-03-25 03:47:21 +08:00
ret = EX_VAR ( opline - > result . var ) ;
ZVAL_STR ( ret , zend_string_alloc ( len , 0 ) ) ;
target = Z_STRVAL_P ( ret ) ;
for ( i = 0 ; i < = opline - > extended_value ; i + + ) {
memcpy ( target , rope [ i ] - > val , rope [ i ] - > len ) ;
target + = rope [ i ] - > len ;
zend_string_release ( rope [ i ] ) ;
}
* target = ' \0 ' ;
2011-04-20 20:59:18 +08:00
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2011-03-16 13:25:02 +08:00
2014-12-05 23:23:39 +08:00
ZEND_VM_HANDLER ( 109 , ZEND_FETCH_CLASS , ANY , CONST | TMPVAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
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 ) ) {
2014-12-14 06:06:14 +08:00
zend_exception_save ( ) ;
2010-04-20 19:16:39 +08:00
}
2004-10-23 05:42:14 +08:00
if ( OP2_TYPE = = IS_UNUSED ) {
2014-12-14 06:06:14 +08:00
Z_CE_P ( EX_VAR ( opline - > result . var ) ) = zend_fetch_class ( NULL , opline - > extended_value ) ;
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-12-05 23:23:39 +08:00
zval * class_name = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2008-06-11 21:18:41 +08:00
2014-12-05 23:23:39 +08:00
ZEND_VM_C_LABEL ( try_class_name ) :
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-12-14 06:06:14 +08:00
Z_CE_P ( EX_VAR ( opline - > result . var ) ) = zend_fetch_class_by_name ( Z_STR_P ( class_name ) , EX_CONSTANT ( opline - > op2 ) + 1 , opline - > extended_value ) ;
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-12-14 06:06:14 +08:00
Z_CE_P ( EX_VAR ( opline - > result . var ) ) = zend_fetch_class ( Z_STR_P ( class_name ) , opline - > extended_value ) ;
2014-12-05 23:23:39 +08:00
} else if ( ( OP2_TYPE & ( IS_VAR | IS_CV ) ) & & Z_TYPE_P ( class_name ) = = IS_REFERENCE ) {
class_name = Z_REFVAL_P ( class_name ) ;
ZEND_VM_C_GOTO ( try_class_name ) ;
2009-04-08 21:19:34 +08:00
} else {
2013-02-16 22:22:22 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | 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
2014-12-08 23:11:14 +08:00
ZEND_VM_HANDLER ( 112 , ZEND_INIT_METHOD_CALL , TMPVAR | UNUSED | CV , CONST | TMPVAR | 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_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 ) ) {
2015-02-26 21:21:48 +08:00
do {
if ( ( OP2_TYPE & ( IS_VAR | IS_CV ) ) & & Z_ISREF_P ( function_name ) ) {
function_name = Z_REFVAL_P ( function_name ) ;
if ( EXPECTED ( Z_TYPE_P ( function_name ) = = IS_STRING ) ) {
2014-12-08 23:11:14 +08:00
break ;
}
}
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Method name must be a string " ) ;
2014-12-08 23:11:14 +08:00
FREE_OP2 ( ) ;
2015-03-09 20:57:15 +08:00
FREE_UNFETCHED_OP1 ( ) ;
HANDLE_EXCEPTION ( ) ;
2015-02-26 21:21:48 +08:00
} while ( 0 ) ;
2004-10-23 05:42:14 +08:00
}
2014-07-06 20:48:42 +08:00
2014-12-08 23:11:14 +08:00
object = GET_OP1_OBJ_ZVAL_PTR ( BP_VAR_R ) ;
2015-03-09 20:57:15 +08:00
if ( OP1_TYPE ! = IS_UNUSED ) {
ZVAL_DEREF ( object ) ;
if ( UNEXPECTED ( Z_TYPE_P ( object ) ! = IS_OBJECT ) ) {
2014-12-08 23:11:14 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
2015-03-10 15:31:55 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Call to a member function %s() on %s " , Z_STRVAL_P ( function_name ) , zend_get_type_by_const ( Z_TYPE_P ( object ) ) ) ;
2014-12-08 23:11:14 +08:00
FREE_OP2 ( ) ;
FREE_OP1 ( ) ;
2015-03-09 20:57:15 +08:00
HANDLE_EXCEPTION ( ) ;
2014-07-06 20:48:42 +08:00
}
2015-03-09 20:57:15 +08:00
}
2008-06-11 21:18:41 +08:00
2014-06-30 19:43:45 +08:00
obj = Z_OBJ_P ( object ) ;
2014-10-09 20:17:30 +08:00
called_scope = obj - > ce ;
2014-06-30 19:43:45 +08:00
if ( OP2_TYPE ! = IS_CONST | |
2015-01-13 20:31:42 +08:00
UNEXPECTED ( ( fbc = CACHED_POLYMORPHIC_PTR ( Z_CACHE_SLOT_P ( function_name ) , called_scope ) ) = = NULL ) ) {
2014-06-30 19:43:45 +08:00
zend_object * orig_obj = obj ;
if ( UNEXPECTED ( obj - > handlers - > get_method = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Object does not support method calls " ) ;
FREE_OP2 ( ) ;
FREE_OP1 ( ) ;
HANDLE_EXCEPTION ( ) ;
2014-06-30 19:43:45 +08:00
}
/* First, locate the function. */
2014-12-14 06:06:14 +08:00
fbc = obj - > handlers - > get_method ( & obj , Z_STR_P ( function_name ) , ( ( OP2_TYPE = = IS_CONST ) ? ( EX_CONSTANT ( opline - > op2 ) + 1 ) : NULL ) ) ;
2014-06-30 19:43:45 +08:00
if ( UNEXPECTED ( fbc = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Call to undefined method %s::%s() " , obj - > ce - > name - > val , Z_STRVAL_P ( function_name ) ) ;
FREE_OP2 ( ) ;
FREE_OP1 ( ) ;
HANDLE_EXCEPTION ( ) ;
2014-06-30 19:43:45 +08:00
}
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 ) ;
}
}
2014-10-10 03:58:41 +08:00
if ( UNEXPECTED ( ( fbc - > common . fn_flags & ZEND_ACC_STATIC ) ! = 0 ) ) {
2014-06-30 19:43:45 +08:00
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-11-28 15:33:03 +08:00
EX ( call ) = zend_vm_stack_push_call_frame ( ZEND_CALL_NESTED_FUNCTION ,
2014-12-14 06:06:14 +08:00
fbc , opline - > extended_value , called_scope , obj , EX ( call ) ) ;
2004-10-23 05:42:14 +08:00
FREE_OP2 ( ) ;
2014-12-08 23:11:14 +08:00
FREE_OP1 ( ) ;
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 ( ) ;
2008-06-11 21:18:41 +08:00
}
2004-10-23 05:42:14 +08:00
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 113 , ZEND_INIT_STATIC_METHOD_CALL , CONST | VAR , CONST | TMPVAR | 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-12-12 15:19:41 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) ) ) {
ce = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) ) ;
2007-09-29 15:28:34 +08:00
} else {
2014-12-14 06:06:14 +08:00
ce = zend_fetch_class_by_name ( Z_STR_P ( EX_CONSTANT ( opline - > op1 ) ) , EX_CONSTANT ( opline - > op1 ) + 1 , ZEND_FETCH_CLASS_DEFAULT ) ;
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 ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Class '%s' not found " , Z_STRVAL_P ( EX_CONSTANT ( opline - > op1 ) ) ) ;
HANDLE_EXCEPTION ( ) ;
2010-05-24 22:11:39 +08:00
}
2014-12-12 15:19:41 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) , 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-12-12 15:19:41 +08:00
CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ) {
fbc = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
2010-05-24 22:11:39 +08:00
} else if ( OP1_TYPE ! = IS_CONST & &
OP2_TYPE = = IS_CONST & &
2014-12-12 15:19:41 +08:00
( fbc = CACHED_POLYMORPHIC_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) , 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 ( ) ;
}
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Function name must be a string " ) ;
FREE_OP2 ( ) ;
HANDLE_EXCEPTION ( ) ;
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-12-14 06:06:14 +08:00
fbc = ce - > get_static_method ( ce , Z_STR_P ( function_name ) ) ;
2014-02-10 14:04:30 +08:00
} else {
2014-12-14 06:06:14 +08:00
fbc = zend_std_get_static_method ( ce , Z_STR_P ( function_name ) , ( ( OP2_TYPE = = IS_CONST ) ? ( EX_CONSTANT ( opline - > op2 ) + 1 ) : NULL ) ) ;
2014-02-10 14:04:30 +08:00
}
2014-06-30 19:43:45 +08:00
if ( UNEXPECTED ( fbc = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Call to undefined method %s::%s() " , ce - > name - > val , Z_STRVAL_P ( function_name ) ) ;
FREE_OP2 ( ) ;
HANDLE_EXCEPTION ( ) ;
2014-02-10 14:04:30 +08:00
}
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 ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot call constructor " ) ;
HANDLE_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
2014-10-09 20:17:30 +08:00
if ( Z_OBJ ( EX ( This ) ) & & Z_OBJ ( EX ( This ) ) - > ce ! = ce - > constructor - > common . scope & & ( ce - > constructor - > common . fn_flags & ZEND_ACC_PRIVATE ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot call private %s::__construct() " , ce - > name - > val ) ;
HANDLE_EXCEPTION ( ) ;
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 ) ) {
2014-10-03 23:32:46 +08:00
if ( Z_OBJ ( EX ( This ) ) ) {
object = Z_OBJ ( EX ( This ) ) ;
2014-07-09 21:07:41 +08:00
GC_REFCOUNT ( object ) + + ;
2014-10-04 18:55:44 +08:00
}
2015-01-19 22:12:51 +08:00
if ( ! object | |
! instanceof_function ( object - > ce , ce ) ) {
/* We are calling method of the other (incompatible) class,
but passing $ this . This is done for compatibility with php - 4. */
2014-10-04 18:55:44 +08:00
if ( fbc - > common . fn_flags & ZEND_ACC_ALLOW_STATIC ) {
2015-01-19 22:12:51 +08:00
zend_error (
object ? E_DEPRECATED : E_STRICT ,
" Non-static method %s::%s() should not be called statically%s " ,
fbc - > common . scope - > name - > val , fbc - > common . function_name - > val ,
object ? " , assuming $this from incompatible context " : " " ) ;
2014-10-04 18:55:44 +08:00
} else {
2015-01-19 22:12:51 +08:00
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
2015-03-09 20:57:15 +08:00
zend_error (
E_EXCEPTION | E_ERROR ,
2015-01-19 22:12:51 +08:00
" Non-static method %s::%s() cannot be called statically%s " ,
fbc - > common . scope - > name - > val , fbc - > common . function_name - > val ,
object ? " , assuming $this from incompatible context " : " " ) ;
2015-03-09 20:57:15 +08:00
HANDLE_EXCEPTION ( ) ;
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-11-28 15:33:03 +08:00
EX ( call ) = zend_vm_stack_push_call_frame ( ZEND_CALL_NESTED_FUNCTION ,
2014-12-14 06:06:14 +08:00
fbc , opline - > extended_value , ce , object , EX ( call ) ) ;
2015-01-03 17:22:58 +08:00
2014-07-09 15:57:42 +08:00
if ( OP2_TYPE = = IS_UNUSED ) {
EX ( call ) - > return_value = NULL ;
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2015-02-25 03:29:47 +08:00
ZEND_VM_HANDLER ( 59 , ZEND_INIT_FCALL_BY_NAME , 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_function * fbc ;
zval * function_name , * func ;
2004-10-23 05:42:14 +08:00
2015-02-25 03:29:47 +08:00
if ( EXPECTED ( CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ) ) {
fbc = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
} else {
2014-12-12 15:19:41 +08:00
function_name = ( zval * ) ( EX_CONSTANT ( opline - > op2 ) + 1 ) ;
2015-02-25 03:29:47 +08:00
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 ( ) ;
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Call to undefined function %s() " , Z_STRVAL_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
HANDLE_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
} else {
2014-06-30 19:43:45 +08:00
fbc = Z_FUNC_P ( func ) ;
2014-12-12 15:19:41 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) , fbc ) ;
2004-10-23 05:42:14 +08:00
}
2015-02-25 03:29:47 +08:00
}
EX ( call ) = zend_vm_stack_push_call_frame ( ZEND_CALL_NESTED_FUNCTION ,
fbc , opline - > extended_value , NULL , NULL , EX ( call ) ) ;
2013-08-29 17:35:11 +08:00
2015-02-25 03:29:47 +08:00
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE ( ) ;
}
2013-08-29 17:35:11 +08:00
2015-02-25 03:29:47 +08:00
ZEND_VM_HANDLER ( 128 , ZEND_INIT_DYNAMIC_CALL , ANY , CONST | TMPVAR | CV )
{
USE_OPLINE
zend_function * fbc ;
zval * function_name , * func ;
zend_string * lcname ;
zend_free_op free_op2 ;
zend_class_entry * called_scope ;
zend_object * object ;
2010-04-20 19:16:39 +08:00
2015-02-25 03:29:47 +08:00
SAVE_OPLINE ( ) ;
function_name = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2014-12-05 23:23:39 +08:00
ZEND_VM_C_LABEL ( try_function_name ) :
2015-02-25 03:29:47 +08:00
if ( OP2_TYPE ! = IS_CONST & & EXPECTED ( Z_TYPE_P ( function_name ) = = IS_STRING ) ) {
if ( Z_STRVAL_P ( function_name ) [ 0 ] = = ' \\ ' ) {
lcname = zend_string_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 ) ;
} else {
lcname = zend_string_tolower ( Z_STR_P ( function_name ) ) ;
}
if ( UNEXPECTED ( ( func = zend_hash_find ( EG ( function_table ) , lcname ) ) = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Call to undefined function %s() " , Z_STRVAL_P ( function_name ) ) ;
2014-12-24 20:04:51 +08:00
zend_string_release ( lcname ) ;
2010-04-20 19:16:39 +08:00
FREE_OP2 ( ) ;
2015-03-09 20:57:15 +08:00
HANDLE_EXCEPTION ( ) ;
2015-02-25 03:29:47 +08:00
}
zend_string_release ( lcname ) ;
FREE_OP2 ( ) ;
2013-08-29 17:35:11 +08:00
2015-02-25 03:29:47 +08:00
fbc = Z_FUNC_P ( func ) ;
called_scope = NULL ;
object = NULL ;
} else if ( OP2_TYPE ! = IS_CONST & &
EXPECTED ( Z_TYPE_P ( function_name ) = = IS_OBJECT ) & &
Z_OBJ_HANDLER_P ( function_name , get_closure ) & &
Z_OBJ_HANDLER_P ( function_name , get_closure ) ( function_name , & called_scope , & fbc , & object ) = = SUCCESS ) {
if ( object ) {
GC_REFCOUNT ( object ) + + ;
}
2015-03-11 04:04:41 +08:00
if ( fbc - > common . fn_flags & ZEND_ACC_CLOSURE ) {
2015-02-25 03:29:47 +08:00
/* Delay closure destruction until its invocation */
2015-03-11 04:04:41 +08:00
ZEND_ASSERT ( GC_TYPE ( fbc - > common . prototype ) = = IS_OBJECT ) ;
GC_REFCOUNT ( fbc - > common . prototype ) + + ;
2015-02-25 03:29:47 +08:00
}
2015-03-11 04:04:41 +08:00
FREE_OP2 ( ) ;
2015-02-25 03:29:47 +08:00
} else if ( EXPECTED ( Z_TYPE_P ( function_name ) = = IS_ARRAY ) & &
zend_hash_num_elements ( Z_ARRVAL_P ( function_name ) ) = = 2 ) {
zval * obj ;
zval * method ;
obj = zend_hash_index_find ( Z_ARRVAL_P ( function_name ) , 0 ) ;
method = zend_hash_index_find ( Z_ARRVAL_P ( function_name ) , 1 ) ;
2013-08-29 17:35:11 +08:00
2015-02-25 03:29:47 +08:00
if ( ! obj | | ! method ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Array callback has to contain indices 0 and 1 " ) ;
FREE_OP2 ( ) ;
HANDLE_EXCEPTION ( ) ;
2015-02-25 03:29:47 +08:00
}
2008-04-21 18:14:20 +08:00
2015-02-25 03:29:47 +08:00
ZVAL_DEREF ( obj ) ;
if ( Z_TYPE_P ( obj ) ! = IS_STRING & & Z_TYPE_P ( obj ) ! = IS_OBJECT ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " First array member is not a valid class name or object " ) ;
FREE_OP2 ( ) ;
HANDLE_EXCEPTION ( ) ;
2015-02-25 03:29:47 +08:00
}
2004-10-23 05:42:14 +08:00
2015-02-25 03:29:47 +08:00
ZVAL_DEREF ( method ) ;
if ( Z_TYPE_P ( method ) ! = IS_STRING ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Second array member is not a valid method " ) ;
FREE_OP2 ( ) ;
HANDLE_EXCEPTION ( ) ;
2015-02-25 03:29:47 +08:00
}
2008-04-21 18:14:20 +08:00
2015-02-25 03:29:47 +08:00
if ( Z_TYPE_P ( obj ) = = IS_STRING ) {
object = NULL ;
called_scope = zend_fetch_class_by_name ( Z_STR_P ( obj ) , NULL , 0 ) ;
if ( UNEXPECTED ( called_scope = = NULL ) ) {
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2010-04-20 19:16:39 +08:00
}
2004-10-23 05:42:14 +08:00
2015-02-25 03:29:47 +08:00
if ( called_scope - > get_static_method ) {
fbc = called_scope - > get_static_method ( called_scope , Z_STR_P ( method ) ) ;
} else {
fbc = zend_std_get_static_method ( called_scope , Z_STR_P ( method ) , NULL ) ;
2008-04-29 16:15:20 +08:00
}
2015-02-25 03:29:47 +08:00
if ( UNEXPECTED ( fbc = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Call to undefined method %s::%s() " , called_scope - > name - > val , Z_STRVAL_P ( method ) ) ;
FREE_OP2 ( ) ;
HANDLE_EXCEPTION ( ) ;
2015-02-25 03:29:47 +08:00
}
if ( ! ( fbc - > common . fn_flags & ZEND_ACC_STATIC ) ) {
if ( fbc - > common . fn_flags & ZEND_ACC_ALLOW_STATIC ) {
zend_error ( E_STRICT ,
2014-10-04 18:55:44 +08:00
" Non-static method %s::%s() should not be called statically " ,
fbc - > common . scope - > name - > val , fbc - > common . function_name - > val ) ;
2012-08-22 18:32:03 +08:00
} else {
2015-03-09 20:57:15 +08:00
zend_error (
E_EXCEPTION | E_ERROR ,
2015-02-25 03:29:47 +08:00
" Non-static method %s::%s() cannot be called statically " ,
fbc - > common . scope - > name - > val , fbc - > common . function_name - > val ) ;
2015-03-09 20:57:15 +08:00
FREE_OP2 ( ) ;
HANDLE_EXCEPTION ( ) ;
2008-04-21 18:14:20 +08:00
}
2005-05-04 16:45:46 +08:00
}
2012-08-22 18:32:03 +08:00
} else {
2015-02-25 03:29:47 +08:00
called_scope = Z_OBJCE_P ( obj ) ;
object = Z_OBJ_P ( obj ) ;
fbc = Z_OBJ_HT_P ( obj ) - > get_method ( & object , Z_STR_P ( method ) , NULL ) ;
if ( UNEXPECTED ( fbc = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Call to undefined method %s::%s() " , object - > ce - > name - > val , Z_STRVAL_P ( method ) ) ;
FREE_OP2 ( ) ;
2013-02-16 22:22:22 +08:00
HANDLE_EXCEPTION ( ) ;
}
2014-06-30 19:43:45 +08:00
2015-02-25 03:29:47 +08:00
if ( ( fbc - > common . fn_flags & ZEND_ACC_STATIC ) ! = 0 ) {
object = NULL ;
} else {
GC_REFCOUNT ( object ) + + ; /* For $this pointer */
}
}
FREE_OP2 ( ) ;
} else if ( ( OP2_TYPE & ( IS_VAR | IS_CV ) ) & & Z_TYPE_P ( function_name ) = = IS_REFERENCE ) {
function_name = Z_REFVAL_P ( function_name ) ;
ZEND_VM_C_GOTO ( try_function_name ) ;
} else {
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Function name must be a string " ) ;
FREE_OP2 ( ) ;
HANDLE_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
2015-02-25 03:29:47 +08:00
EX ( call ) = zend_vm_stack_push_call_frame ( ZEND_CALL_NESTED_FUNCTION ,
fbc , opline - > extended_value , called_scope , object , EX ( call ) ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2012-08-22 18:32:03 +08:00
}
2004-10-23 05:42:14 +08:00
2014-12-05 22:04:15 +08:00
ZEND_VM_HANDLER ( 118 , ZEND_INIT_USER_CALL , CONST , CONST | TMPVAR | CV )
2014-07-11 04:32:18 +08:00
{
USE_OPLINE
zend_free_op free_op2 ;
2015-03-13 01:39:04 +08:00
zval * function_name ;
2014-07-11 04:32:18 +08:00
zend_fcall_info_cache fcc ;
char * error = NULL ;
zend_function * func ;
zend_class_entry * called_scope ;
zend_object * object ;
2015-03-13 01:39:04 +08:00
SAVE_OPLINE ( ) ;
function_name = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2014-12-14 06:06:14 +08:00
if ( zend_is_callable_ex ( function_name , NULL , 0 , NULL , & fcc , & error ) ) {
2014-07-11 04:32:18 +08:00
if ( error ) {
efree ( error ) ;
}
func = fcc . function_handler ;
if ( func - > common . fn_flags & ZEND_ACC_CLOSURE ) {
/* Delay closure destruction until its invocation */
2015-03-11 04:04:41 +08:00
if ( OP2_TYPE & ( IS_VAR | IS_CV ) ) {
ZVAL_DEREF ( function_name ) ;
}
ZEND_ASSERT ( GC_TYPE ( func - > common . prototype ) = = IS_OBJECT ) ;
GC_REFCOUNT ( func - > common . prototype ) + + ;
2014-07-11 04:32:18 +08:00
}
called_scope = fcc . called_scope ;
object = fcc . object ;
if ( object ) {
GC_REFCOUNT ( object ) + + ; /* For $this pointer */
2014-10-04 18:55:44 +08:00
} else if ( func - > common . scope & &
! ( func - > common . fn_flags & ZEND_ACC_STATIC ) ) {
if ( func - > common . fn_flags & ZEND_ACC_ALLOW_STATIC ) {
zend_error ( E_STRICT ,
" Non-static method %s::%s() should not be called statically " ,
func - > common . scope - > name - > val , func - > common . function_name - > val ) ;
} else {
2015-03-09 20:57:15 +08:00
zend_error (
E_EXCEPTION | E_ERROR ,
2014-10-04 18:55:44 +08:00
" Non-static method %s::%s() cannot be called statically " ,
func - > common . scope - > name - > val , func - > common . function_name - > val ) ;
2015-03-09 20:57:15 +08:00
FREE_OP2 ( ) ;
HANDLE_EXCEPTION ( ) ;
2014-10-04 18:55:44 +08:00
}
2014-07-11 04:32:18 +08:00
}
} else {
2015-03-20 01:30:11 +08:00
zend_internal_type_error ( EX_USES_STRICT_TYPES ( ) , " %s() expects parameter 1 to be a valid callback, %s " , Z_STRVAL_P ( EX_CONSTANT ( opline - > op1 ) ) , error ) ;
2014-07-11 04:32:18 +08:00
efree ( error ) ;
func = ( zend_function * ) & zend_pass_function ;
called_scope = NULL ;
object = NULL ;
}
2014-11-28 15:33:03 +08:00
EX ( call ) = zend_vm_stack_push_call_frame ( ZEND_CALL_NESTED_FUNCTION ,
2014-12-14 06:06:14 +08:00
func , opline - > extended_value , called_scope , object , EX ( call ) ) ;
2014-07-11 04:32:18 +08:00
FREE_OP2 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
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-12-12 15:19:41 +08:00
func_name = EX_CONSTANT ( opline - > op2 ) + 1 ;
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ) {
fbc = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
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 ( ) ;
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Call to undefined function %s() " , Z_STRVAL_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
HANDLE_EXCEPTION ( ) ;
2012-08-22 18:32:03 +08:00
} else {
2014-06-30 19:43:45 +08:00
fbc = Z_FUNC_P ( func ) ;
2014-12-12 15:19:41 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) , 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 ) ;
2014-12-12 15:19:41 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) , fbc ) ;
2004-10-23 05:42:14 +08:00
}
2014-11-28 15:33:03 +08:00
EX ( call ) = zend_vm_stack_push_call_frame ( ZEND_CALL_NESTED_FUNCTION ,
2014-12-14 06:06:14 +08:00
fbc , opline - > extended_value , NULL , NULL , EX ( call ) ) ;
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 ( ) ;
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Call to undefined function %s() " , Z_STRVAL_P ( fname ) ) ;
HANDLE_EXCEPTION ( ) ;
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-12-16 23:40:52 +08:00
EX ( call ) = zend_vm_stack_push_call_frame_ex (
opline - > op1 . num , ZEND_CALL_NESTED_FUNCTION ,
2014-12-17 00:13:47 +08:00
fbc , opline - > extended_value , NULL , NULL , EX ( call ) ) ;
2004-10-23 05:42:14 +08:00
2014-06-30 19:43:45 +08:00
FREE_OP2 ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2015-02-25 15:37:21 +08:00
ZEND_VM_HANDLER ( 129 , ZEND_DO_ICALL , ANY , ANY )
{
USE_OPLINE
zend_execute_data * call = EX ( call ) ;
zend_function * fbc = call - > func ;
zval * ret ;
SAVE_OPLINE ( ) ;
EX ( call ) = call - > prev_execute_data ;
call - > called_scope = EX ( called_scope ) ;
Z_OBJ ( call - > This ) = Z_OBJ ( EX ( This ) ) ;
call - > prev_execute_data = execute_data ;
EG ( current_execute_data ) = call ;
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 ;
fbc - > internal_function . handler ( call , ret ) ;
2015-03-24 17:21:06 +08:00
# if ZEND_DEBUG
2015-02-25 15:37:21 +08:00
ZEND_ASSERT (
! call - > func | |
! ( call - > func - > common . fn_flags & ZEND_ACC_HAS_RETURN_TYPE ) | |
2015-03-20 21:04:04 +08:00
zend_verify_internal_return_type ( call - > func , EX_VAR ( opline - > result . var ) ) ) ;
2015-03-24 17:21:06 +08:00
# endif
2015-02-25 15:37:21 +08:00
EG ( current_execute_data ) = call - > prev_execute_data ;
zend_vm_stack_free_args ( call ) ;
zend_vm_stack_free_call_frame ( call ) ;
if ( ! RETURN_VALUE_USED ( opline ) ) {
zval_ptr_dtor ( EX_VAR ( opline - > result . var ) ) ;
}
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
zend_throw_exception_internal ( NULL ) ;
if ( RETURN_VALUE_USED ( opline ) ) {
zval_ptr_dtor ( EX_VAR ( opline - > result . var ) ) ;
}
HANDLE_EXCEPTION ( ) ;
}
2015-03-17 00:48:29 +08:00
ZEND_VM_INTERRUPT_CHECK ( ) ;
2015-02-25 15:37:21 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 130 , ZEND_DO_UCALL , ANY , ANY )
{
USE_OPLINE
zend_execute_data * call = EX ( call ) ;
zend_function * fbc = call - > func ;
zval * ret ;
SAVE_OPLINE ( ) ;
EX ( call ) = call - > prev_execute_data ;
EG ( scope ) = NULL ;
ret = NULL ;
call - > symbol_table = NULL ;
if ( RETURN_VALUE_USED ( opline ) ) {
ret = EX_VAR ( opline - > result . var ) ;
ZVAL_NULL ( ret ) ;
Z_VAR_FLAGS_P ( ret ) = 0 ;
}
call - > prev_execute_data = execute_data ;
i_init_func_execute_data ( call , & fbc - > op_array , ret , 0 ) ;
2014-07-11 04:32:18 +08:00
2015-02-25 15:37:21 +08:00
ZEND_VM_ENTER ( ) ;
2014-07-11 04:32:18 +08:00
}
2008-04-21 18:14:20 +08:00
2015-02-25 15:37:21 +08:00
ZEND_VM_HANDLER ( 131 , ZEND_DO_FCALL_BY_NAME , ANY , ANY )
2012-08-22 18:32:03 +08:00
{
USE_OPLINE
2015-02-25 15:37:21 +08:00
zend_execute_data * call = EX ( call ) ;
zend_function * fbc = call - > func ;
zval * ret ;
2012-08-22 18:32:03 +08:00
2015-02-25 15:37:21 +08:00
SAVE_OPLINE ( ) ;
EX ( call ) = call - > prev_execute_data ;
if ( EXPECTED ( fbc - > type = = ZEND_USER_FUNCTION ) ) {
EG ( scope ) = NULL ;
if ( UNEXPECTED ( ( fbc - > common . fn_flags & ZEND_ACC_GENERATOR ) ! = 0 ) ) {
if ( RETURN_VALUE_USED ( opline ) ) {
zend_generator_create_zval ( call , & fbc - > op_array , EX_VAR ( opline - > result . var ) ) ;
} else {
zend_vm_stack_free_args ( call ) ;
}
zend_vm_stack_free_call_frame ( call ) ;
2012-08-22 18:32:03 +08:00
} else {
2015-02-25 15:37:21 +08:00
ret = NULL ;
call - > symbol_table = NULL ;
if ( RETURN_VALUE_USED ( opline ) ) {
ret = EX_VAR ( opline - > result . var ) ;
ZVAL_NULL ( ret ) ;
Z_VAR_FLAGS_P ( ret ) = 0 ;
}
call - > prev_execute_data = execute_data ;
i_init_func_execute_data ( call , & fbc - > op_array , ret , 0 ) ;
ZEND_VM_ENTER ( ) ;
2004-10-23 05:42:14 +08:00
}
2015-02-25 15:37:21 +08:00
EG ( scope ) = EX ( func ) - > op_array . scope ;
2012-08-22 18:32:03 +08:00
} else {
2015-02-25 15:37:21 +08:00
ZEND_ASSERT ( fbc - > type = = ZEND_INTERNAL_FUNCTION ) ;
2004-10-23 05:42:14 +08:00
2015-02-25 15:37:21 +08:00
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 ( ) ;
}
}
2014-02-10 14:04:30 +08:00
2015-02-25 15:37:21 +08:00
call - > called_scope = EX ( called_scope ) ;
Z_OBJ ( call - > This ) = Z_OBJ ( EX ( This ) ) ;
2004-10-23 05:42:14 +08:00
2015-02-25 15:37:21 +08:00
call - > prev_execute_data = execute_data ;
EG ( current_execute_data ) = call ;
2004-10-23 05:42:14 +08:00
2015-02-25 15:37:21 +08:00
if ( fbc - > common . fn_flags & ZEND_ACC_HAS_TYPE_HINTS ) {
uint32_t i ;
uint32_t num_args = ZEND_CALL_NUM_ARGS ( call ) ;
zval * p = ZEND_CALL_ARG ( call , 1 ) ;
2013-08-29 17:35:11 +08:00
2015-02-25 15:37:21 +08:00
for ( i = 0 ; i < num_args ; + + i ) {
2015-03-20 21:04:04 +08:00
zend_verify_internal_arg_type ( fbc , i + 1 , p ) ;
2015-02-25 15:37:21 +08:00
p + + ;
}
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
EG ( current_execute_data ) = call - > prev_execute_data ;
zend_vm_stack_free_args ( call ) ;
zend_vm_stack_free_call_frame ( call ) ;
zend_throw_exception_internal ( NULL ) ;
HANDLE_EXCEPTION ( ) ;
}
}
2004-10-23 05:42:14 +08:00
2015-02-25 15:37:21 +08:00
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 ;
fbc - > internal_function . handler ( call , ret ) ;
2015-03-24 17:21:06 +08:00
# if ZEND_DEBUG
2015-02-25 15:37:21 +08:00
ZEND_ASSERT (
! call - > func | |
! ( call - > func - > common . fn_flags & ZEND_ACC_HAS_RETURN_TYPE ) | |
2015-03-20 21:04:04 +08:00
zend_verify_internal_return_type ( call - > func , EX_VAR ( opline - > result . var ) ) ) ;
2015-03-24 17:21:06 +08:00
# endif
2015-02-25 15:37:21 +08:00
EG ( current_execute_data ) = call - > prev_execute_data ;
zend_vm_stack_free_args ( call ) ;
zend_vm_stack_free_call_frame ( call ) ;
if ( ! RETURN_VALUE_USED ( opline ) ) {
zval_ptr_dtor ( EX_VAR ( opline - > result . var ) ) ;
}
}
2014-06-30 19:43:45 +08:00
2015-02-25 15:37:21 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
zend_throw_exception_internal ( NULL ) ;
if ( RETURN_VALUE_USED ( opline ) ) {
zval_ptr_dtor ( EX_VAR ( opline - > result . var ) ) ;
}
HANDLE_EXCEPTION ( ) ;
}
2015-03-17 00:48:29 +08:00
ZEND_VM_INTERRUPT_CHECK ( ) ;
2014-06-30 19:43:45 +08:00
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 ;
2014-10-03 23:32:46 +08:00
zend_object * object = Z_OBJ ( call - > This ) ;
2014-12-29 18:38:36 +08:00
zval * ret ;
2014-06-30 19:43:45 +08:00
SAVE_OPLINE ( ) ;
2014-10-01 14:46:13 +08:00
EX ( call ) = call - > prev_execute_data ;
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 ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot call abstract method %s::%s() " , fbc - > common . scope - > name - > val , fbc - > common . function_name - > val ) ;
HANDLE_EXCEPTION ( ) ;
2014-06-30 19:43:45 +08:00
}
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 ( ) ;
}
}
}
LOAD_OPLINE ( ) ;
2014-12-29 19:20:52 +08:00
if ( EXPECTED ( fbc - > type = = ZEND_USER_FUNCTION ) ) {
EG ( scope ) = fbc - > common . scope ;
if ( UNEXPECTED ( ( fbc - > common . fn_flags & ZEND_ACC_GENERATOR ) ! = 0 ) ) {
if ( RETURN_VALUE_USED ( opline ) ) {
zend_generator_create_zval ( call , & fbc - > op_array , EX_VAR ( opline - > result . var ) ) ;
} else {
zend_vm_stack_free_args ( call ) ;
}
2015-01-03 17:22:58 +08:00
2014-12-29 19:20:52 +08:00
zend_vm_stack_free_call_frame ( call ) ;
} else {
ret = NULL ;
call - > symbol_table = NULL ;
if ( RETURN_VALUE_USED ( opline ) ) {
ret = EX_VAR ( opline - > result . var ) ;
ZVAL_NULL ( ret ) ;
Z_VAR_FLAGS_P ( ret ) = 0 ;
}
call - > prev_execute_data = execute_data ;
2015-02-25 15:37:21 +08:00
i_init_func_execute_data ( call , & fbc - > op_array , ret , 1 ) ;
2014-12-29 19:20:52 +08:00
if ( EXPECTED ( zend_execute_ex = = execute_ex ) ) {
ZEND_VM_ENTER ( ) ;
} else {
ZEND_ADD_CALL_FLAG ( call , ZEND_CALL_TOP ) ;
zend_execute_ex ( call ) ;
}
}
} else if ( EXPECTED ( fbc - > type < ZEND_USER_FUNCTION ) ) {
2014-12-16 06:44:10 +08:00
int should_change_scope = 0 ;
2014-06-30 19:43:45 +08:00
if ( fbc - > common . scope ) {
2014-12-16 06:44:10 +08:00
should_change_scope = 1 ;
2014-06-30 19:43:45 +08:00
/* TODO: we don't set scope if we call an object method ??? */
/* See: ext/pdo_sqlite/tests/pdo_fetch_func_001.phpt */
# if 1
2014-10-03 23:32:46 +08:00
EG ( scope ) = object ? NULL : fbc - > common . scope ;
2015-01-03 17:22:58 +08:00
# else
2014-06-30 19:43:45 +08:00
EG ( scope ) = fbc - > common . scope ;
# endif
2015-01-03 17:22:58 +08:00
} else {
2014-07-03 06:34:43 +08:00
call - > called_scope = EX ( called_scope ) ;
2014-10-03 23:32:46 +08:00
Z_OBJ ( call - > This ) = Z_OBJ ( EX ( This ) ) ;
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 ) {
2014-08-26 01:28:33 +08:00
uint32_t i ;
2014-12-23 00:04:29 +08:00
uint32_t num_args = ZEND_CALL_NUM_ARGS ( call ) ;
2014-06-30 19:43:45 +08:00
zval * p = ZEND_CALL_ARG ( call , 1 ) ;
2014-12-23 00:04:29 +08:00
for ( i = 0 ; i < num_args ; + + i ) {
2015-03-20 21:04:04 +08:00
zend_verify_internal_arg_type ( fbc , i + 1 , p ) ;
2015-03-09 20:57:15 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
EG ( current_execute_data ) = call - > prev_execute_data ;
zend_vm_stack_free_args ( call ) ;
zend_vm_stack_free_call_frame ( call ) ;
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 ) ;
}
2014-06-30 19:43:45 +08:00
}
2015-03-09 20:57:15 +08:00
p + + ;
2014-06-30 19:43:45 +08:00
}
}
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 */
2014-12-14 06:06:14 +08:00
fbc - > internal_function . handler ( call , ret ) ;
2014-06-30 19:43:45 +08:00
} else {
2014-12-14 06:06:14 +08:00
zend_execute_internal ( call , ret ) ;
2014-06-30 19:43:45 +08:00
}
2015-02-11 22:41:21 +08:00
2015-03-24 17:21:06 +08:00
# if ZEND_DEBUG
2015-02-11 22:41:21 +08:00
ZEND_ASSERT (
! call - > func | |
! ( call - > func - > common . fn_flags & ZEND_ACC_HAS_RETURN_TYPE ) | |
2015-03-20 21:04:04 +08:00
zend_verify_internal_return_type ( call - > func , EX_VAR ( opline - > result . var ) ) ) ;
2015-03-24 17:21:06 +08:00
# endif
2015-02-11 22:41:21 +08:00
2015-01-03 17:22:58 +08:00
EG ( current_execute_data ) = call - > prev_execute_data ;
2014-12-14 06:06:14 +08:00
zend_vm_stack_free_args ( call ) ;
zend_vm_stack_free_call_frame ( call ) ;
2014-06-30 19:43:45 +08:00
if ( ! RETURN_VALUE_USED ( opline ) ) {
2014-12-29 19:21:16 +08:00
zval_ptr_dtor ( EX_VAR ( opline - > result . var ) ) ;
2014-06-30 19:43:45 +08:00
}
2004-10-23 05:42:14 +08:00
2014-12-16 06:44:10 +08:00
if ( UNEXPECTED ( should_change_scope ) ) {
2014-06-30 19:43:45 +08:00
ZEND_VM_C_GOTO ( fcall_end_change_scope ) ;
} else {
ZEND_VM_C_GOTO ( fcall_end ) ;
}
} else { /* ZEND_OVERLOADED_FUNCTION */
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 */
2014-10-03 23:32:46 +08:00
if ( EXPECTED ( 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-12-14 06:06:14 +08:00
object - > handlers - > call_method ( fbc - > common . function_name , object , call , EX_VAR ( opline - > result . var ) ) ;
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 {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot call overloaded function for non-object " ) ;
2015-03-11 16:54:51 +08:00
#if 0
//TODO: implement clean exit ???
2015-03-11 13:42:39 +08:00
zend_vm_stack_free_args ( call ) ;
zend_vm_stack_free_call_frame ( call ) ;
if ( fbc - > type = = ZEND_OVERLOADED_FUNCTION_TEMPORARY ) {
zend_string_release ( fbc - > common . function_name ) ;
}
efree ( fbc ) ;
2015-03-11 16:54:51 +08:00
# endif
2015-03-09 20:57:15 +08:00
HANDLE_EXCEPTION ( ) ;
2014-06-30 19:43:45 +08:00
}
2014-12-14 06:06:14 +08:00
zend_vm_stack_free_args ( call ) ;
2014-06-30 19:43:45 +08:00
2014-12-14 06:06:14 +08:00
zend_vm_stack_free_call_frame ( call ) ;
2014-06-30 19:43:45 +08:00
if ( fbc - > type = = ZEND_OVERLOADED_FUNCTION_TEMPORARY ) {
2014-08-26 01:24:55 +08:00
zend_string_release ( fbc - > common . function_name ) ;
2014-06-30 19:43:45 +08:00
}
efree ( fbc ) ;
if ( ! RETURN_VALUE_USED ( opline ) ) {
zval_ptr_dtor ( EX_VAR ( opline - > result . var ) ) ;
} else {
Z_VAR_FLAGS_P ( EX_VAR ( opline - > result . var ) ) = 0 ;
}
}
ZEND_VM_C_LABEL ( fcall_end_change_scope ) :
2014-10-03 23:32:46 +08:00
if ( object ) {
2014-06-30 19:43:45 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) & & ( opline - > op1 . num & ZEND_CALL_CTOR ) ) {
if ( ! ( opline - > op1 . num & ZEND_CALL_CTOR_RESULT_UNUSED ) ) {
2014-10-03 23:32:46 +08:00
GC_REFCOUNT ( object ) - - ;
2014-06-30 19:43:45 +08:00
}
2014-10-03 23:32:46 +08:00
if ( GC_REFCOUNT ( object ) = = 1 ) {
2014-12-14 06:06:14 +08:00
zend_object_store_ctor_failed ( object ) ;
2014-06-30 19:43:45 +08:00
}
}
2014-10-03 23:32:46 +08:00
OBJ_RELEASE ( object ) ;
2014-06-30 19:43:45 +08:00
}
2014-11-28 15:21:18 +08:00
EG ( scope ) = EX ( func ) - > op_array . scope ;
2014-06-30 19:43:45 +08:00
ZEND_VM_C_LABEL ( fcall_end ) :
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2014-12-14 06:06:14 +08:00
zend_throw_exception_internal ( NULL ) ;
2014-06-30 19:43:45 +08:00
if ( RETURN_VALUE_USED ( opline ) ) {
zval_ptr_dtor ( EX_VAR ( opline - > result . var ) ) ;
}
HANDLE_EXCEPTION ( ) ;
}
2015-03-17 00:48:29 +08:00
ZEND_VM_INTERRUPT_CHECK ( ) ;
2014-06-30 19:43:45 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
2004-10-23 05:42:14 +08:00
}
2015-01-09 04:40:36 +08:00
ZEND_VM_HANDLER ( 124 , ZEND_VERIFY_RETURN_TYPE , CONST | TMP | VAR | UNUSED | CV , UNUSED )
{
2015-02-26 22:53:03 +08:00
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
2015-01-09 04:40:36 +08:00
USE_OPLINE
2015-01-31 16:50:17 +08:00
# endif
2015-03-20 23:36:43 +08:00
2015-01-09 04:40:36 +08:00
SAVE_OPLINE ( ) ;
if ( OP1_TYPE = = IS_UNUSED ) {
zend_verify_missing_return_type ( EX ( func ) ) ;
} else {
2015-02-03 04:07:46 +08:00
/* prevents "undefined variable opline" errors */
2015-03-20 23:36:43 +08:00
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
2015-03-24 17:48:16 +08:00
zval * retval_ref , * retval_ptr ;
2015-01-09 04:40:36 +08:00
zend_free_op free_op1 ;
2015-03-20 05:47:43 +08:00
zend_arg_info * ret_info = EX ( func ) - > common . arg_info - 1 ;
2015-01-09 04:40:36 +08:00
2015-03-24 17:48:16 +08:00
retval_ref = retval_ptr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2015-03-20 16:10:29 +08:00
2015-03-21 05:22:25 +08:00
if ( OP1_TYPE = = IS_CONST ) {
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , retval_ptr ) ;
2015-03-24 17:48:16 +08:00
retval_ref = retval_ptr = EX_VAR ( opline - > result . var ) ;
} else if ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) {
ZVAL_DEREF ( retval_ptr ) ;
2015-03-21 05:22:25 +08:00
}
2015-03-20 16:10:29 +08:00
if ( UNEXPECTED ( ! ret_info - > class_name
& & ret_info - > type_hint ! = IS_CALLABLE
2015-03-20 05:47:43 +08:00
& & ! ZEND_SAME_FAKE_TYPE ( ret_info - > type_hint , Z_TYPE_P ( retval_ptr ) ) ) ) {
/* A cast or an error will happen, so separate the zval to prevent overwriting it */
2015-03-20 16:10:29 +08:00
2015-03-20 23:36:43 +08:00
if ( EXPECTED ( ( EX ( func ) - > op_array . fn_flags & ZEND_ACC_RETURN_REFERENCE ) = = 0 ) ) {
2015-03-20 05:47:43 +08:00
/* Does not return by reference */
2015-03-24 17:48:16 +08:00
if ( retval_ref ! = retval_ptr & & Z_REFCOUNT_P ( retval_ref ) = = 1 ) {
ZVAL_UNREF ( retval_ref ) ;
} else {
SEPARATE_ZVAL ( retval_ref ) ;
}
retval_ptr = retval_ref ;
2015-03-20 05:47:43 +08:00
} else {
SEPARATE_ZVAL_NOREF ( retval_ptr ) ;
}
2015-03-19 06:10:08 +08:00
}
2015-03-20 21:04:04 +08:00
zend_verify_return_type ( EX ( func ) , retval_ptr ) ;
2015-02-03 04:07:46 +08:00
# endif
2015-01-09 04:40:36 +08:00
}
CHECK_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 {
2015-01-03 17:22:58 +08:00
if ( OP1_TYPE = = IS_CONST | | OP1_TYPE = = IS_TMP_VAR ) {
2014-03-04 21:38:19 +08:00
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-09-22 20:17:35 +08:00
} else if ( ( OP1_TYPE = = IS_CV | | OP1_TYPE = = IS_VAR ) & & 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 {
2015-01-03 17:22:58 +08:00
if ( OP1_TYPE = = IS_CONST | | OP1_TYPE = = IS_TMP_VAR | |
2013-11-28 00:30:35 +08:00
( 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-10-08 02:38:37 +08:00
Z_VAR_FLAGS_P ( EX ( return_value ) ) = IS_VAR_RET_REF ;
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-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( retval_ptr = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot return string offsets by reference " ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
2014-10-23 01:45:02 +08:00
if ( OP1_TYPE = = IS_VAR ) {
if ( retval_ptr = = & EG ( uninitialized_zval ) | |
( opline - > extended_value = = ZEND_RETURNS_FUNCTION & &
! ( Z_VAR_FLAGS_P ( retval_ptr ) & IS_VAR_RET_REF ) ) ) {
2014-03-04 16:27:50 +08:00
zend_error ( E_NOTICE , " Only variable references should be returned by reference " ) ;
if ( EX ( return_value ) ) {
2014-09-22 20:17:35 +08:00
ZVAL_NEW_REF ( EX ( return_value ) , retval_ptr ) ;
2014-10-08 02:38:37 +08:00
Z_VAR_FLAGS_P ( EX ( return_value ) ) = IS_VAR_RET_REF ;
2014-09-22 20:17:35 +08:00
if ( Z_REFCOUNTED_P ( retval_ptr ) ) Z_ADDREF_P ( retval_ptr ) ;
2014-03-04 16:27:50 +08:00
}
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 ) ) ;
2014-10-08 02:38:37 +08:00
Z_VAR_FLAGS_P ( EX ( return_value ) ) = IS_VAR_RET_REF ;
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
}
2015-02-20 03:17:37 +08:00
ZEND_VM_HANDLER ( 161 , ZEND_GENERATOR_RETURN , CONST | TMP | VAR | CV , ANY )
2012-08-24 19:51:39 +08:00
{
2015-02-20 03:17:37 +08:00
USE_OPLINE
zval * retval ;
zend_free_op free_op1 ;
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
2015-02-20 03:17:37 +08:00
SAVE_OPLINE ( ) ;
retval = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
/* Copy return value into generator->retval */
if ( OP1_TYPE = = IS_CONST | | OP1_TYPE = = IS_TMP_VAR ) {
ZVAL_COPY_VALUE ( & generator - > retval , retval ) ;
if ( OP1_TYPE = = IS_CONST ) {
if ( UNEXPECTED ( Z_OPT_COPYABLE ( generator - > retval ) ) ) {
zval_copy_ctor_func ( & generator - > retval ) ;
}
}
} else if ( ( OP1_TYPE = = IS_CV | | OP1_TYPE = = IS_VAR ) & & Z_ISREF_P ( retval ) ) {
ZVAL_COPY ( & generator - > retval , Z_REFVAL_P ( retval ) ) ;
FREE_OP1_IF_VAR ( ) ;
} else {
ZVAL_COPY_VALUE ( & generator - > retval , retval ) ;
if ( OP1_TYPE = = IS_CV ) {
if ( Z_OPT_REFCOUNTED_P ( retval ) ) Z_ADDREF_P ( retval ) ;
}
}
2012-12-11 21:25:32 +08:00
/* Close the generator to free up resources */
2014-12-14 06:06:14 +08:00
zend_generator_close ( generator , 1 ) ;
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-12-08 23:11:14 +08:00
value = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2014-12-08 23:11:14 +08:00
do {
if ( OP1_TYPE = = IS_CONST | | UNEXPECTED ( Z_TYPE_P ( value ) ! = IS_OBJECT ) ) {
if ( ( OP1_TYPE & ( IS_VAR | IS_CV ) ) & & Z_ISREF_P ( value ) ) {
value = Z_REFVAL_P ( value ) ;
if ( EXPECTED ( Z_TYPE_P ( value ) = = IS_OBJECT ) ) {
break ;
}
}
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Can only throw objects " ) ;
FREE_OP1 ( ) ;
HANDLE_EXCEPTION ( ) ;
2013-02-16 22:22:22 +08:00
}
2014-12-08 23:11:14 +08:00
} while ( 0 ) ;
2013-02-16 22:22:22 +08:00
2014-12-14 06:06:14 +08:00
zend_exception_save ( ) ;
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-12-14 06:06:14 +08:00
zend_throw_exception_object ( value ) ;
zend_exception_restore ( ) ;
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 */
2014-12-14 06:06:14 +08:00
zend_exception_restore ( ) ;
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-12-12 15:19:41 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) ) ) {
catch_ce = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-12-14 06:06:14 +08:00
catch_ce = zend_fetch_class_by_name ( Z_STR_P ( EX_CONSTANT ( opline - > op1 ) ) , EX_CONSTANT ( opline - > op1 ) + 1 , ZEND_FETCH_CLASS_NO_AUTOLOAD ) ;
2012-05-13 13:12:48 +08:00
2014-12-12 15:19:41 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) , catch_ce ) ;
2010-05-24 22:11:39 +08:00
}
2014-10-09 20:17:30 +08:00
ce = EG ( exception ) - > ce ;
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 ) {
2015-01-14 20:06:26 +08:00
if ( ! catch_ce | | ! instanceof_function ( ce , catch_ce ) ) {
2010-04-20 18:57:45 +08:00
if ( opline - > result . num ) {
2014-12-14 06:06:14 +08:00
zend_throw_exception_internal ( NULL ) ;
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-11-25 06:22:59 +08:00
zval_ptr_dtor ( EX_VAR ( opline - > op2 . var ) ) ;
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-07-08 06:13:53 +08:00
value = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-12-16 23:40:52 +08:00
arg = ZEND_CALL_VAR ( EX ( call ) , opline - > result . var ) ;
2014-07-08 06:13:53 +08:00
ZVAL_COPY_VALUE ( arg , value ) ;
if ( OP1_TYPE = = IS_CONST ) {
if ( UNEXPECTED ( Z_OPT_COPYABLE_P ( arg ) ) ) {
zval_copy_ctor_func ( arg ) ;
2013-08-29 17:35:11 +08:00
}
2004-10-23 05:42:14 +08:00
}
2014-07-08 06:13:53 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2013-08-29 17:35:11 +08:00
2014-07-08 06:13:53 +08:00
ZEND_VM_HANDLER ( 116 , ZEND_SEND_VAL_EX , CONST | TMP , ANY )
{
USE_OPLINE
zval * value , * arg ;
zend_free_op free_op1 ;
SAVE_OPLINE ( ) ;
if ( ARG_MUST_BE_SENT_BY_REF ( EX ( call ) - > func , opline - > op2 . num ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot pass parameter %d by reference " , opline - > op2 . num ) ;
FREE_UNFETCHED_OP1 ( ) ;
2015-03-10 19:05:14 +08:00
arg = ZEND_CALL_VAR ( EX ( call ) , opline - > result . var ) ;
ZVAL_UNDEF ( arg ) ;
2015-03-09 20:57:15 +08:00
HANDLE_EXCEPTION ( ) ;
2014-07-08 06:13:53 +08:00
}
2014-04-22 16:33:00 +08:00
value = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-12-16 23:40:52 +08:00
arg = ZEND_CALL_VAR ( EX ( call ) , opline - > result . var ) ;
2014-06-30 19:43:45 +08:00
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 ( ) ;
}
2014-07-08 06:13:53 +08:00
ZEND_VM_HANDLER ( 117 , ZEND_SEND_VAR , VAR | CV , 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 * varptr , * arg ;
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2015-03-13 01:39:04 +08:00
SAVE_OPLINE ( ) ;
2014-02-10 14:04:30 +08:00
varptr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-12-16 23:40:52 +08:00
arg = ZEND_CALL_VAR ( EX ( call ) , opline - > result . var ) ;
2014-12-05 17:40:47 +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 ( ) ;
2014-11-18 19:37:36 +08:00
if ( ! ( opline - > extended_value & ZEND_ARG_COMPILE_TIME_BOUND ) ) {
2014-06-30 19:43:45 +08:00
if ( ! ARG_SHOULD_BE_SENT_BY_REF ( EX ( call ) - > func , opline - > op2 . num ) ) {
2014-07-08 06:13:53 +08:00
ZEND_VM_DISPATCH_TO_HANDLER ( ZEND_SEND_VAR ) ;
2013-08-29 17:35:11 +08:00
}
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-08-20 19:04:40 +08:00
( Z_ISREF_P ( varptr ) | | Z_TYPE_P ( varptr ) = = IS_OBJECT ) ) {
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
}
} 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-03-05 03:54:05 +08:00
}
2014-11-18 19:37:36 +08:00
2014-12-16 23:40:52 +08:00
arg = ZEND_CALL_VAR ( EX ( call ) , opline - > result . var ) ;
2014-11-18 19:37:36 +08:00
ZVAL_COPY_VALUE ( arg , varptr ) ;
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-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( varptr = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Only variables can be passed by reference " ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
2014-12-16 23:40:52 +08:00
arg = ZEND_CALL_VAR ( EX ( call ) , opline - > result . var ) ;
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-11-13 22:36:08 +08:00
ZVAL_NEW_REF ( arg , varptr ) ;
2014-03-13 04:30:53 +08:00
} else {
2014-11-13 22:36:08 +08:00
ZVAL_NEW_REF ( arg , varptr ) ;
Z_ADDREF_P ( arg ) ;
ZVAL_REF ( varptr , Z_REF_P ( arg ) ) ;
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 ( ) ;
}
2014-07-08 06:13:53 +08:00
ZEND_VM_HANDLER ( 66 , ZEND_SEND_VAR_EX , VAR | CV , 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 * varptr , * arg ;
2014-04-22 16:33:00 +08:00
zend_free_op free_op1 ;
2004-10-23 05:42:14 +08:00
2014-07-08 06:13:53 +08:00
if ( ARG_SHOULD_BE_SENT_BY_REF ( EX ( call ) - > func , opline - > op2 . num ) ) {
ZEND_VM_DISPATCH_TO_HANDLER ( ZEND_SEND_REF ) ;
2004-10-23 05:42:14 +08:00
}
2015-03-13 01:39:04 +08:00
SAVE_OPLINE ( ) ;
2014-04-22 16:33:00 +08:00
varptr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-12-16 23:40:52 +08:00
arg = ZEND_CALL_VAR ( EX ( call ) , opline - > result . var ) ;
2014-12-05 17:40:47 +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 ( ) ;
2015-03-13 01:39:04 +08:00
SAVE_OPLINE ( ) ;
2013-08-29 17:35:11 +08:00
args = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-11-28 15:28:49 +08:00
arg_num = ZEND_CALL_NUM_ARGS ( EX ( call ) ) + 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-12-14 06:06:14 +08:00
zend_vm_stack_extend_call_frame ( & EX ( call ) , arg_num - 1 , zend_hash_num_elements ( ht ) ) ;
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 ) ) {
2014-09-15 21:52:39 +08:00
uint32_t i ;
2014-05-29 22:21:56 +08:00
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 ) {
2015-03-10 15:31:55 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot unpack array with string keys " ) ;
2013-08-29 17:35:11 +08:00
FREE_OP1 ( ) ;
2015-03-09 20:57:15 +08:00
HANDLE_EXCEPTION ( ) ;
2013-08-29 17:35:11 +08:00
}
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-07-08 17:24:23 +08:00
ZVAL_COPY ( 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-11-28 15:28:49 +08:00
ZEND_CALL_NUM_ARGS ( EX ( call ) ) + + ;
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 ;
}
2014-12-14 06:06:14 +08:00
iter = ce - > get_iterator ( ce , args , 0 ) ;
2013-08-29 17:35:11 +08:00
if ( UNEXPECTED ( ! iter ) ) {
FREE_OP1 ( ) ;
if ( ! EG ( exception ) ) {
zend_throw_exception_ex (
2014-12-14 06:06:14 +08:00
NULL , 0 , " 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 ) {
2014-12-14 06:06:14 +08:00
iter - > funcs - > rewind ( iter ) ;
2013-08-29 17:35:11 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
ZEND_VM_C_GOTO ( unpack_iter_dtor ) ;
}
}
2014-12-14 06:06:14 +08:00
for ( ; iter - > funcs - > valid ( iter ) = = 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-12-14 06:06:14 +08:00
arg = iter - > funcs - > get_current_data ( iter ) ;
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 ;
2014-12-14 06:06:14 +08:00
iter - > funcs - > get_current_key ( iter , & key ) ;
2013-08-29 17:35:11 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
ZEND_VM_C_GOTO ( unpack_iter_dtor ) ;
}
if ( Z_TYPE ( key ) = = IS_STRING ) {
2015-03-10 15:31:55 +08:00
zend_error ( E_EXCEPTION | E_ERROR ,
2013-08-29 17:35:11 +08:00
" Cannot unpack Traversable with string keys " ) ;
2014-11-25 06:22:59 +08:00
zend_string_release ( Z_STR ( key ) ) ;
2013-08-29 17:35:11 +08:00
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
) ;
}
2015-01-03 17:22:58 +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-12-14 06:06:14 +08:00
zend_vm_stack_extend_call_frame ( & EX ( call ) , arg_num - 1 , 1 ) ;
2014-06-30 19:43:45 +08:00
top = ZEND_CALL_ARG ( EX ( call ) , arg_num ) ;
ZVAL_COPY_VALUE ( top , arg ) ;
2014-11-28 15:28:49 +08:00
ZEND_CALL_NUM_ARGS ( EX ( call ) ) + + ;
2013-08-29 17:35:11 +08:00
2014-12-14 06:06:14 +08:00
iter - > funcs - > move_forward ( iter ) ;
2013-08-29 17:35:11 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
ZEND_VM_C_GOTO ( unpack_iter_dtor ) ;
}
}
ZEND_VM_C_LABEL ( unpack_iter_dtor ) :
2014-12-14 06:06:14 +08:00
zend_iterator_dtor ( iter ) ;
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 ( ) ;
}
2014-07-11 04:32:18 +08:00
ZEND_VM_HANDLER ( 119 , ZEND_SEND_ARRAY , ANY , ANY )
{
USE_OPLINE
zend_free_op free_op1 ;
zval * args ;
SAVE_OPLINE ( ) ;
2015-03-13 01:39:04 +08:00
SAVE_OPLINE ( ) ;
2014-12-08 23:11:14 +08:00
args = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-07-11 04:32:18 +08:00
2014-12-08 23:11:14 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( args ) ! = IS_ARRAY ) ) {
if ( ( OP1_TYPE & ( IS_VAR | IS_CV ) ) & & Z_ISREF_P ( args ) ) {
args = Z_REFVAL_P ( args ) ;
if ( EXPECTED ( Z_TYPE_P ( args ) = = IS_ARRAY ) ) {
ZEND_VM_C_GOTO ( send_array ) ;
}
}
2015-03-20 01:30:11 +08:00
zend_internal_type_error ( EX_USES_STRICT_TYPES ( ) , " call_user_func_array() expects parameter 2 to be array, %s given " , zend_get_type_by_const ( Z_TYPE_P ( args ) ) ) ;
2014-07-11 04:32:18 +08:00
if ( EX ( call ) - > func - > common . fn_flags & ZEND_ACC_CLOSURE ) {
OBJ_RELEASE ( ( zend_object * ) EX ( call ) - > func - > common . prototype ) ;
}
2014-10-03 23:32:46 +08:00
if ( Z_OBJ ( EX ( call ) - > This ) ) {
OBJ_RELEASE ( Z_OBJ ( EX ( call ) - > This ) ) ;
2014-07-11 04:32:18 +08:00
}
EX ( call ) - > func = ( zend_function * ) & zend_pass_function ;
EX ( call ) - > called_scope = NULL ;
2014-10-03 23:32:46 +08:00
Z_OBJ ( EX ( call ) - > This ) = NULL ;
2014-07-11 04:32:18 +08:00
} else {
2014-12-08 23:11:14 +08:00
uint32_t arg_num ;
HashTable * ht ;
2014-07-11 04:32:18 +08:00
zval * arg , * param , tmp ;
2014-12-08 23:11:14 +08:00
ZEND_VM_C_LABEL ( send_array ) :
ht = Z_ARRVAL_P ( args ) ;
2014-12-14 06:06:14 +08:00
zend_vm_stack_extend_call_frame ( & EX ( call ) , 0 , zend_hash_num_elements ( ht ) ) ;
2014-07-11 04:32:18 +08:00
if ( OP1_TYPE ! = IS_CONST & & OP1_TYPE ! = IS_TMP_VAR & & Z_IMMUTABLE_P ( args ) ) {
int separate = 0 ;
/* check if any of arguments are going to be passed by reference */
2014-12-22 17:31:00 +08:00
for ( arg_num = 0 ; arg_num < zend_hash_num_elements ( ht ) ; arg_num + + ) {
2014-12-22 12:18:56 +08:00
if ( ARG_SHOULD_BE_SENT_BY_REF ( EX ( call ) - > func , arg_num + 1 ) ) {
2014-07-11 04:32:18 +08:00
separate = 1 ;
break ;
}
}
if ( separate ) {
zval_copy_ctor ( args ) ;
ht = Z_ARRVAL_P ( args ) ;
}
}
2014-12-16 23:40:52 +08:00
arg_num = 1 ;
param = ZEND_CALL_ARG ( EX ( call ) , 1 ) ;
2014-07-11 04:32:18 +08:00
ZEND_HASH_FOREACH_VAL ( ht , arg ) {
if ( ARG_SHOULD_BE_SENT_BY_REF ( EX ( call ) - > func , arg_num ) ) {
// TODO: Scalar values don't have reference counters anymore.
// They are assumed to be 1, and they may be easily passed by
// reference now. However, previously scalars with refcount==1
// might be passed and with refcount>1 might not. We can support
// only single behavior ???
#if 0
if ( Z_REFCOUNTED_P ( arg ) & &
// This solution breaks the following test (omit warning message) ???
// Zend/tests/bug61273.phpt
// ext/reflection/tests/bug42976.phpt
// ext/standard/tests/general_functions/call_user_func_array_variation_001.phpt
# else
if ( ! Z_REFCOUNTED_P ( arg ) | |
// This solution breaks the following test (emit warning message) ???
// ext/pdo_sqlite/tests/pdo_005.phpt
# endif
( ! Z_ISREF_P ( arg ) & & Z_REFCOUNT_P ( arg ) > 1 ) ) {
if ( ! ARG_MAY_BE_SENT_BY_REF ( EX ( call ) - > func , arg_num ) ) {
zend_error ( E_WARNING , " Parameter %d to %s%s%s() expected to be a reference, value given " ,
arg_num ,
EX ( call ) - > func - > common . scope ? EX ( call ) - > func - > common . scope - > name - > val : " " ,
EX ( call ) - > func - > common . scope ? " :: " : " " ,
EX ( call ) - > func - > common . function_name - > val ) ;
if ( EX ( call ) - > func - > common . fn_flags & ZEND_ACC_CLOSURE ) {
OBJ_RELEASE ( ( zend_object * ) EX ( call ) - > func - > common . prototype ) ;
}
2014-10-03 23:32:46 +08:00
if ( Z_OBJ ( EX ( call ) - > This ) ) {
OBJ_RELEASE ( Z_OBJ ( EX ( call ) - > This ) ) ;
2014-07-11 04:32:18 +08:00
}
EX ( call ) - > func = ( zend_function * ) & zend_pass_function ;
EX ( call ) - > called_scope = NULL ;
2014-10-03 23:32:46 +08:00
Z_OBJ ( EX ( call ) - > This ) = NULL ;
2014-07-11 04:32:18 +08:00
break ;
}
if ( Z_REFCOUNTED_P ( arg ) ) {
Z_DELREF_P ( arg ) ;
}
ZVAL_DUP ( & tmp , arg ) ;
ZVAL_NEW_REF ( arg , & tmp ) ;
Z_ADDREF_P ( arg ) ;
} else if ( ! Z_ISREF_P ( arg ) ) {
ZVAL_NEW_REF ( arg , arg ) ;
Z_ADDREF_P ( arg ) ;
} else if ( Z_REFCOUNTED_P ( arg ) ) {
Z_ADDREF_P ( arg ) ;
}
ZVAL_COPY_VALUE ( param , arg ) ;
} else if ( Z_ISREF_P ( arg ) & &
/* don't separate references for __call */
( EX ( call ) - > func - > common . fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) = = 0 ) {
ZVAL_DUP ( param , Z_REFVAL_P ( arg ) ) ;
} else {
ZVAL_COPY ( param , arg ) ;
}
2014-11-28 15:28:49 +08:00
ZEND_CALL_NUM_ARGS ( EX ( call ) ) + + ;
2014-07-11 04:32:18 +08:00
arg_num + + ;
param + + ;
} ZEND_HASH_FOREACH_END ( ) ;
}
FREE_OP1 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 120 , ZEND_SEND_USER , VAR | CV , ANY )
{
USE_OPLINE
zval * arg , * param , tmp ;
zend_free_op free_op1 ;
2015-03-13 01:39:04 +08:00
SAVE_OPLINE ( ) ;
2014-07-11 04:32:18 +08:00
arg = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2014-12-16 23:40:52 +08:00
param = ZEND_CALL_VAR ( EX ( call ) , opline - > result . var ) ;
2014-07-11 04:32:18 +08:00
if ( ARG_SHOULD_BE_SENT_BY_REF ( EX ( call ) - > func , opline - > op2 . num ) ) {
// TODO: Scalar values don't have reference counters anymore.
// They are assumed to be 1, and they may be easily passed by
// reference now. However, previously scalars with refcount==1
// might be passed and with refcount>1 might not. We can support
// only single behavior ???
#if 0
if ( Z_REFCOUNTED_P ( arg ) & &
// This solution breaks the following test (omit warning message) ???
// Zend/tests/bug61273.phpt
// ext/reflection/tests/bug42976.phpt
// ext/standard/tests/general_functions/call_user_func_array_variation_001.phpt
# else
if ( ! Z_REFCOUNTED_P ( arg ) | |
// This solution breaks the following test (emit warning message) ???
// ext/pdo_sqlite/tests/pdo_005.phpt
# endif
2014-07-30 00:27:48 +08:00
( ! Z_ISREF_P ( arg ) /*&& Z_REFCOUNT_P(arg) > 1???*/ ) ) {
2014-07-11 04:32:18 +08:00
if ( ! ARG_MAY_BE_SENT_BY_REF ( EX ( call ) - > func , opline - > op2 . num ) ) {
zend_error ( E_WARNING , " Parameter %d to %s%s%s() expected to be a reference, value given " ,
opline - > op2 . num ,
EX ( call ) - > func - > common . scope ? EX ( call ) - > func - > common . scope - > name - > val : " " ,
EX ( call ) - > func - > common . scope ? " :: " : " " ,
EX ( call ) - > func - > common . function_name - > val ) ;
if ( EX ( call ) - > func - > common . fn_flags & ZEND_ACC_CLOSURE ) {
OBJ_RELEASE ( ( zend_object * ) EX ( call ) - > func - > common . prototype ) ;
}
2014-10-03 23:32:46 +08:00
if ( Z_OBJ ( EX ( call ) - > This ) ) {
OBJ_RELEASE ( Z_OBJ ( EX ( call ) - > This ) ) ;
2014-07-11 04:32:18 +08:00
}
2015-01-26 14:41:45 +08:00
ZVAL_UNDEF ( param ) ;
2014-07-11 04:32:18 +08:00
EX ( call ) - > func = ( zend_function * ) & zend_pass_function ;
EX ( call ) - > called_scope = NULL ;
2014-10-03 23:32:46 +08:00
Z_OBJ ( EX ( call ) - > This ) = NULL ;
2014-07-11 04:32:18 +08:00
FREE_OP1 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
if ( Z_REFCOUNTED_P ( arg ) ) {
Z_DELREF_P ( arg ) ;
}
ZVAL_DUP ( & tmp , arg ) ;
ZVAL_NEW_REF ( arg , & tmp ) ;
Z_ADDREF_P ( arg ) ;
} else if ( ! Z_ISREF_P ( arg ) ) {
ZVAL_NEW_REF ( arg , arg ) ;
Z_ADDREF_P ( arg ) ;
} else if ( Z_REFCOUNTED_P ( arg ) ) {
Z_ADDREF_P ( arg ) ;
}
ZVAL_COPY_VALUE ( param , arg ) ;
} else if ( Z_ISREF_P ( arg ) & &
/* don't separate references for __call */
( EX ( call ) - > func - > common . fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) = = 0 ) {
ZVAL_DUP ( param , Z_REFVAL_P ( arg ) ) ;
} else {
ZVAL_COPY ( param , arg ) ;
}
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
2014-08-26 01:28:33 +08:00
uint32_t arg_num = opline - > op1 . num ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-11-28 15:28:49 +08:00
if ( UNEXPECTED ( arg_num > EX_NUM_ARGS ( ) ) ) {
2014-12-14 06:06:14 +08:00
zend_verify_missing_arg ( execute_data , arg_num ) ;
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 ) ) {
2014-12-14 06:06:14 +08:00
zval * param = _get_zval_ptr_cv_undef_BP_VAR_W ( execute_data , opline - > result . var ) ;
2004-10-23 05:42:14 +08:00
2015-03-20 21:04:04 +08:00
zend_verify_arg_type ( EX ( func ) , arg_num , param , NULL ) ;
2014-06-30 19:43:45 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 64 , ZEND_RECV_INIT , ANY , CONST )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2014-08-26 01:28:33 +08:00
uint32_t arg_num = opline - > op1 . num ;
2014-11-25 20:40:08 +08:00
zval * param ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-12-14 06:06:14 +08:00
param = _get_zval_ptr_cv_undef_BP_VAR_W ( execute_data , opline - > result . var ) ;
2014-11-28 15:28:49 +08:00
if ( arg_num > EX_NUM_ARGS ( ) ) {
2014-12-12 15:19:41 +08:00
ZVAL_COPY_VALUE ( param , EX_CONSTANT ( opline - > op2 ) ) ;
2014-11-25 20:40:08 +08:00
if ( Z_OPT_CONSTANT_P ( param ) ) {
2014-12-14 06:06:14 +08:00
zval_update_constant ( param , 0 ) ;
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 ) ) {
2015-03-20 21:04:04 +08:00
zend_verify_arg_type ( EX ( func ) , arg_num , param , EX_CONSTANT ( opline - > op2 ) ) ;
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
2014-08-26 01:28:33 +08:00
uint32_t arg_num = opline - > op1 . num ;
2014-11-28 15:28:49 +08:00
uint32_t 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-12-14 06:06:14 +08:00
params = _get_zval_ptr_cv_undef_BP_VAR_W ( execute_data , opline - > result . var ) ;
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-12-24 00:08:28 +08:00
zend_hash_real_init ( Z_ARRVAL_P ( params ) , 1 ) ;
ZEND_HASH_FILL_PACKED ( Z_ARRVAL_P ( params ) ) {
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 ) ) {
2015-03-20 16:10:29 +08:00
do {
2015-03-20 21:04:04 +08:00
zend_verify_arg_type ( EX ( func ) , arg_num , param , NULL ) ;
2014-12-24 00:08:28 +08:00
if ( Z_OPT_REFCOUNTED_P ( param ) ) Z_ADDREF_P ( param ) ;
ZEND_HASH_FILL_ADD ( param ) ;
param + + ;
} while ( + + arg_num < = arg_count ) ;
} else {
do {
if ( Z_OPT_REFCOUNTED_P ( param ) ) Z_ADDREF_P ( param ) ;
ZEND_HASH_FILL_ADD ( param ) ;
param + + ;
} while ( + + arg_num < = arg_count ) ;
}
} ZEND_HASH_FILL_END ( ) ;
2013-09-27 00:39:17 +08:00
} else {
array_init ( params ) ;
}
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 52 , ZEND_BOOL , CONST | TMPVAR | CV , ANY )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2014-12-05 22:04:15 +08:00
zval * val ;
2004-10-23 05:42:14 +08:00
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-12-05 22:04:15 +08:00
val = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2015-01-03 17:22:58 +08:00
if ( Z_TYPE_P ( val ) = = IS_TRUE ) {
2014-12-05 22:04:15 +08:00
ZVAL_TRUE ( EX_VAR ( opline - > result . var ) ) ;
} else if ( EXPECTED ( Z_TYPE_P ( val ) < = IS_TRUE ) ) {
ZVAL_FALSE ( EX_VAR ( opline - > result . var ) ) ;
} else {
2014-12-14 06:06:14 +08:00
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , i_zend_is_true ( val ) ) ;
2014-12-05 22:04:15 +08:00
FREE_OP1 ( ) ;
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 ( ) ;
2014-12-12 15:19:41 +08:00
el = zend_brk_cont ( Z_LVAL_P ( EX_CONSTANT ( opline - > op2 ) ) , opline - > op1 . opline_num ,
2014-12-14 06:06:14 +08:00
& EX ( func ) - > op_array , execute_data ) ;
2014-06-30 19:43:45 +08:00
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 ( ) ;
2014-12-12 15:19:41 +08:00
el = zend_brk_cont ( Z_LVAL_P ( EX_CONSTANT ( opline - > op2 ) ) , opline - > op1 . opline_num ,
2014-12-14 06:06:14 +08:00
& EX ( func ) - > op_array , execute_data ) ;
2014-06-30 19:43:45 +08:00
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 ( ) ;
2014-12-12 15:19:41 +08:00
el = zend_brk_cont ( Z_LVAL_P ( EX_CONSTANT ( opline - > op2 ) ) , opline - > extended_value ,
2014-12-14 06:06:14 +08:00
& EX ( func ) - > op_array , execute_data ) ;
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-09-23 21:21:29 +08:00
if ( brk_opline - > opcode = = ZEND_FREE ) {
2014-06-05 22:42:17 +08:00
if ( ! ( brk_opline - > extended_value & EXT_TYPE_FREE_ON_RETURN ) ) {
2014-09-23 21:21:29 +08:00
zval_ptr_dtor_nogc ( EX_VAR ( brk_opline - > op1 . var ) ) ;
2014-06-05 22:42:17 +08:00
}
2015-02-12 18:57:12 +08:00
} else if ( brk_opline - > opcode = = ZEND_FE_FREE ) {
if ( ! ( brk_opline - > extended_value & EXT_TYPE_FREE_ON_RETURN ) ) {
zval * var = EX_VAR ( brk_opline - > op1 . var ) ;
if ( Z_TYPE_P ( var ) ! = IS_ARRAY & & Z_FE_ITER_P ( var ) ! = ( uint32_t ) - 1 ) {
zend_hash_iterator_del ( Z_FE_ITER_P ( var ) ) ;
}
zval_ptr_dtor_nogc ( var ) ;
}
2008-03-28 22:35:01 +08:00
}
2014-12-12 15:19:41 +08:00
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op1 ) ) ;
2008-03-28 22:35:01 +08:00
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 48 , ZEND_CASE , CONST | TMPVAR | CV , CONST | TMPVAR | 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 ;
2015-03-17 23:53:19 +08:00
zval * op1 , * op2 , * result ;
2004-10-23 05:42:14 +08:00
2015-03-17 23:53:19 +08:00
op1 = GET_OP1_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
op2 = GET_OP2_ZVAL_PTR_UNDEF ( BP_VAR_R ) ;
if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_LONG ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_LONG ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , Z_LVAL_P ( op1 ) = = Z_LVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_DOUBLE ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , ( double ) Z_LVAL_P ( op1 ) = = Z_DVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
} else if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_DOUBLE ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_DOUBLE ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , Z_DVAL_P ( op1 ) = = Z_DVAL_P ( op2 ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_LONG ) ) {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , Z_DVAL_P ( op1 ) = = ( ( double ) Z_LVAL_P ( op2 ) ) ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
} else if ( EXPECTED ( Z_TYPE_P ( op1 ) = = IS_STRING ) ) {
if ( EXPECTED ( Z_TYPE_P ( op2 ) = = IS_STRING ) ) {
if ( Z_STR_P ( op1 ) = = Z_STR_P ( op2 ) ) {
ZVAL_TRUE ( EX_VAR ( opline - > result . var ) ) ;
FREE_OP2 ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( Z_STRVAL_P ( op1 ) [ 0 ] > ' 9 ' | | Z_STRVAL_P ( op2 ) [ 0 ] > ' 9 ' ) {
if ( Z_STRLEN_P ( op1 ) ! = Z_STRLEN_P ( op2 ) ) {
ZVAL_FALSE ( EX_VAR ( opline - > result . var ) ) ;
FREE_OP2 ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , memcmp ( Z_STRVAL_P ( op1 ) , Z_STRVAL_P ( op2 ) , Z_STRLEN_P ( op1 ) ) = = 0 ) ;
FREE_OP2 ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
} else {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , zendi_smart_strcmp ( op1 , op2 ) = = 0 ) ;
FREE_OP2 ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
}
}
2004-10-23 05:42:14 +08:00
2015-03-17 23:53:19 +08:00
SAVE_OPLINE ( ) ;
if ( OP1_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op1 ) = = IS_UNDEF ) ) {
op1 = GET_OP1_UNDEF_CV ( op1 , BP_VAR_R ) ;
}
if ( OP2_TYPE = = IS_CV & & UNEXPECTED ( Z_TYPE_P ( op2 ) = = IS_UNDEF ) ) {
op2 = GET_OP2_UNDEF_CV ( op2 , BP_VAR_R ) ;
}
result = EX_VAR ( opline - > result . var ) ;
compare_function ( result , op1 , op2 ) ;
ZVAL_BOOL ( result , Z_LVAL_P ( result ) = = 0 ) ;
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 ( ) ;
}
2014-10-23 15:52:34 +08:00
ZEND_VM_HANDLER ( 68 , ZEND_NEW , CONST | VAR , ANY )
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 object_zval ;
2005-06-10 15:56:40 +08:00
zend_function * constructor ;
2014-10-23 15:52:34 +08:00
zend_class_entry * ce ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-10-23 15:52:34 +08:00
if ( OP1_TYPE = = IS_CONST ) {
2014-12-12 15:19:41 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) ) ) {
ce = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) ) ;
2014-10-23 15:52:34 +08:00
} else {
2014-12-14 06:06:14 +08:00
ce = zend_fetch_class_by_name ( Z_STR_P ( EX_CONSTANT ( opline - > op1 ) ) , EX_CONSTANT ( opline - > op1 ) + 1 , 0 ) ;
2014-10-23 15:52:34 +08:00
if ( UNEXPECTED ( ce = = NULL ) ) {
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-12-12 15:19:41 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) , ce ) ;
2014-10-23 15:52:34 +08:00
}
} else {
ce = Z_CE_P ( EX_VAR ( opline - > op1 . var ) ) ;
}
2015-02-13 06:19:14 +08:00
if ( UNEXPECTED ( ( ce - > ce_flags & ( ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS ) ) ! = 0 ) ) {
2014-10-23 15:52:34 +08:00
if ( ce - > ce_flags & ZEND_ACC_INTERFACE ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot instantiate interface %s " , ce - > name - > val ) ;
2015-02-13 06:19:14 +08:00
} else if ( ce - > ce_flags & ZEND_ACC_TRAIT ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot instantiate trait %s " , ce - > name - > val ) ;
2004-10-23 05:42:14 +08:00
} else {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot instantiate abstract class %s " , ce - > name - > val ) ;
2004-10-23 05:42:14 +08:00
}
2015-03-09 20:57:15 +08:00
HANDLE_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
2014-10-23 15:52:34 +08:00
object_init_ex ( & object_zval , ce ) ;
2014-12-14 06:06:14 +08:00
constructor = Z_OBJ_HT ( object_zval ) - > get_constructor ( Z_OBJ ( object_zval ) ) ;
2005-06-10 15:56:40 +08:00
if ( constructor = = NULL ) {
2014-12-09 22:07:12 +08:00
if ( EXPECTED ( 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 {
2014-11-25 06:22:59 +08:00
OBJ_RELEASE ( Z_OBJ ( object_zval ) ) ;
2005-06-10 15:56:40 +08:00
}
2014-12-12 15:19:41 +08:00
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
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 (
2014-11-28 15:33:03 +08:00
ZEND_CALL_FUNCTION | ZEND_CALL_CTOR |
2014-12-09 22:07:12 +08:00
( EXPECTED ( RETURN_VALUE_USED ( opline ) ) ? 0 : ZEND_CALL_CTOR_RESULT_UNUSED ) ,
2014-10-07 21:12:12 +08:00
constructor ,
opline - > extended_value ,
2014-10-23 15:52:34 +08:00
ce ,
2014-06-30 19:43:45 +08:00
Z_OBJ ( object_zval ) ,
2014-12-14 06:06:14 +08:00
EX ( call ) ) ;
2012-11-30 17:39:23 +08:00
2014-12-09 22:07:12 +08:00
if ( EXPECTED ( RETURN_VALUE_USED ( opline ) ) ) {
2014-02-10 14:04:30 +08:00
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , & object_zval ) ;
2014-07-09 15:57:42 +08:00
EX ( call ) - > return_value = EX_VAR ( opline - > result . var ) ;
} else {
EX ( call ) - > return_value = NULL ;
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
}
2014-12-08 23:11:14 +08:00
ZEND_VM_HANDLER ( 110 , ZEND_CLONE , CONST | TMPVAR | UNUSED | 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
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-12-08 23:11:14 +08:00
obj = GET_OP1_OBJ_ZVAL_PTR ( BP_VAR_R ) ;
2010-04-20 19:16:39 +08:00
2014-12-08 23:11:14 +08:00
do {
if ( OP1_TYPE = = IS_CONST | |
( OP1_TYPE ! = IS_UNUSED & & UNEXPECTED ( Z_TYPE_P ( obj ) ! = IS_OBJECT ) ) ) {
if ( ( OP1_TYPE & ( IS_VAR | IS_CV ) ) & & Z_ISREF_P ( obj ) ) {
obj = Z_REFVAL_P ( obj ) ;
if ( EXPECTED ( Z_TYPE_P ( obj ) = = IS_OBJECT ) ) {
break ;
}
}
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
HANDLE_EXCEPTION ( ) ;
}
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " __clone method called on non-object " ) ;
FREE_OP1 ( ) ;
HANDLE_EXCEPTION ( ) ;
2013-02-16 22:22:22 +08:00
}
2014-12-08 23:11:14 +08:00
} while ( 0 ) ;
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 ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Trying to clone an uncloneable object of class %s " , ce - > name - > val ) ;
2006-07-27 18:44:03 +08:00
} else {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Trying to clone an uncloneable object " ) ;
2006-07-27 18:44:03 +08:00
}
2015-03-09 20:57:15 +08:00
FREE_OP1 ( ) ;
HANDLE_EXCEPTION ( ) ;
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-11-28 15:21:18 +08:00
if ( UNEXPECTED ( ce ! = EG ( scope ) ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Call to private %s::__clone() from context '%s' " , ce - > name - > val , EG ( scope ) ? EG ( scope ) - > name - > val : " " ) ;
FREE_OP1 ( ) ;
HANDLE_EXCEPTION ( ) ;
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-11-28 15:21:18 +08:00
if ( UNEXPECTED ( ! zend_check_protected ( zend_get_function_root_class ( clone ) , EG ( scope ) ) ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Call to protected %s::__clone() from context '%s' " , ce - > name - > val , EG ( scope ) ? EG ( scope ) - > name - > val : " " ) ;
FREE_OP1 ( ) ;
HANDLE_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
}
}
2010-04-20 19:16:39 +08:00
if ( EXPECTED ( EG ( exception ) = = NULL ) ) {
2014-12-14 06:06:14 +08:00
ZVAL_OBJ ( EX_VAR ( opline - > result . var ) , clone_call ( obj ) ) ;
2014-12-09 22:07:12 +08:00
if ( UNEXPECTED ( ! RETURN_VALUE_USED ( opline ) ) | | UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2014-11-25 06:22:59 +08:00
OBJ_RELEASE ( Z_OBJ_P ( EX_VAR ( opline - > result . var ) ) ) ;
2006-06-08 16:56:27 +08:00
}
2004-10-23 05:42:14 +08:00
}
2014-12-08 23:11: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 ( ) ;
}
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-12-12 15:19:41 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ) {
c = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
2014-12-14 06:06:14 +08:00
} else if ( ( c = zend_quick_get_constant ( EX_CONSTANT ( opline - > op2 ) + 1 , opline - > extended_value ) ) = = NULL ) {
2008-11-12 03:45:29 +08:00
if ( ( opline - > extended_value & IS_CONSTANT_UNQUALIFIED ) ! = 0 ) {
2014-12-12 15:19:41 +08:00
char * actual = ( char * ) zend_memrchr ( Z_STRVAL_P ( EX_CONSTANT ( opline - > op2 ) ) , ' \\ ' , Z_STRLEN_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
2014-10-30 16:00:08 +08:00
if ( ! actual ) {
2015-03-12 21:53:51 +08:00
ZVAL_STR_COPY ( EX_VAR ( opline - > result . var ) , Z_STR_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
2008-11-12 03:45:29 +08:00
} else {
actual + + ;
2014-10-30 16:55:40 +08:00
ZVAL_STRINGL ( EX_VAR ( opline - > result . var ) ,
2014-12-12 15:19:41 +08:00
actual , Z_STRLEN_P ( EX_CONSTANT ( opline - > op2 ) ) - ( actual - Z_STRVAL_P ( EX_CONSTANT ( opline - > op2 ) ) ) ) ;
2008-11-04 23:58:55 +08:00
}
2008-11-12 03:45:29 +08:00
/* non-qualified constant - allow text substitution */
2014-10-30 16:55:40 +08:00
zend_error ( E_NOTICE , " Use of undefined constant %s - assumed '%s' " ,
Z_STRVAL_P ( EX_VAR ( opline - > result . var ) ) , Z_STRVAL_P ( EX_VAR ( opline - > result . var ) ) ) ;
2010-04-27 20:09:13 +08:00
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2008-11-04 23:58:55 +08:00
} else {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Undefined constant '%s' " , Z_STRVAL_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
HANDLE_EXCEPTION ( ) ;
2007-12-08 01:11:24 +08:00
}
2010-05-24 22:11:39 +08:00
} else {
2014-12-12 15:19:41 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) , 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 ) ) {
2014-08-05 19:38:43 +08:00
if ( Z_OPT_COPYABLE_P ( retval ) ) {
2014-06-05 20:04:11 +08:00
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-12-12 15:19:41 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ) {
value = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
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-12-12 15:19:41 +08:00
} else if ( CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) ) ) {
ce = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-12-14 06:06:14 +08:00
ce = zend_fetch_class_by_name ( Z_STR_P ( EX_CONSTANT ( opline - > op1 ) ) , EX_CONSTANT ( opline - > op1 ) + 1 , 0 ) ;
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 ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Class '%s' not found " , Z_STRVAL_P ( EX_CONSTANT ( opline - > op1 ) ) ) ;
HANDLE_EXCEPTION ( ) ;
2010-05-24 22:11:39 +08:00
}
2014-12-12 15:19:41 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) , 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-12-12 15:19:41 +08:00
if ( ( value = CACHED_POLYMORPHIC_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) , 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-12-12 15:19:41 +08:00
if ( EXPECTED ( ( value = zend_hash_find ( & ce - > constants_table , Z_STR_P ( EX_CONSTANT ( opline - > op2 ) ) ) ) ! = 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
EG ( scope ) = ce ;
2014-12-14 06:06:14 +08:00
zval_update_constant ( value , 1 ) ;
2014-11-28 15:21:18 +08:00
EG ( scope ) = EX ( func ) - > op_array . scope ;
2007-09-29 03:52:53 +08:00
}
2010-05-24 22:11:39 +08:00
if ( OP1_TYPE = = IS_CONST ) {
2014-12-12 15:19:41 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) , value ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-12-12 15:19:41 +08:00
CACHE_POLYMORPHIC_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) , 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 ) ;
2014-12-12 15:19:41 +08:00
} else if ( Z_STRLEN_P ( EX_CONSTANT ( opline - > op2 ) ) = = sizeof ( " class " ) - 1 & & memcmp ( Z_STRVAL_P ( EX_CONSTANT ( opline - > op2 ) ) , " 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-09-19 21:32:50 +08:00
ZVAL_STR_COPY ( EX_VAR ( opline - > result . var ) , ce - > name ) ;
2007-09-29 03:52:53 +08:00
} else {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Undefined class constant '%s' " , Z_STRVAL_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
HANDLE_EXCEPTION ( ) ;
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
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 72 , ZEND_ADD_ARRAY_ELEMENT , CONST | TMP | VAR | CV , CONST | TMPVAR | 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-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( expr_ptr = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot create references to/from string offsets " ) ;
FREE_OP1_VAR_PTR ( ) ;
2015-03-11 04:04:41 +08:00
zend_array_destroy ( Z_ARRVAL_P ( EX_VAR ( opline - > result . var ) ) ) ;
2015-03-09 20:57:15 +08:00
HANDLE_EXCEPTION ( ) ;
2010-10-22 19:05:22 +08:00
}
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 ) ;
2014-09-22 16:47:10 +08:00
if ( OP1_TYPE = = IS_TMP_VAR ) {
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-09-22 20:17:35 +08:00
} else if ( ( OP1_TYPE = = IS_CV | | OP1_TYPE = = IS_VAR ) & & Z_ISREF_P ( expr_ptr ) ) {
expr_ptr = Z_REFVAL_P ( expr_ptr ) ;
if ( Z_REFCOUNTED_P ( expr_ptr ) ) Z_ADDREF_P ( expr_ptr ) ;
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 ;
2014-08-26 01:24:55 +08:00
zend_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 :
2014-08-26 01:24:55 +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 ) ;
2014-08-26 01:24:55 +08:00
case IS_LONG :
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
}
2015-01-03 17:22:58 +08:00
ZEND_VM_C_LABEL ( str_index ) :
2014-04-23 06:47:41 +08:00
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 ( ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 71 , ZEND_INIT_ARRAY , CONST | TMP | VAR | UNUSED | CV , CONST | TMPVAR | UNUSED | CV )
2004-10-23 05:42:14 +08:00
{
2014-04-23 06:47:41 +08:00
zval * array ;
2014-08-26 01:28:33 +08:00
uint32_t 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 ( ) ;
2015-02-26 22:53:03 +08:00
# if !defined(ZEND_VM_SPEC) || (OP1_TYPE != IS_UNUSED)
2006-09-18 22:23:52 +08:00
} 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-12-08 23:11:14 +08:00
expr = GET_OP1_ZVAL_PTR ( 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 ) {
2014-12-14 06:06:14 +08:00
if ( Z_OBJ_HT_P ( expr ) - > cast_object ( expr , result , IS_NULL ) = = SUCCESS ) {
2014-04-25 21:41:23 +08:00
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-12-14 06:06:14 +08:00
ZVAL_BOOL ( result , zend_is_true ( expr ) ) ;
2004-10-23 05:42:14 +08:00
break ;
2014-08-26 01:24:55 +08:00
case IS_LONG :
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 :
2014-12-08 23:11:14 +08:00
if ( OP1_TYPE & ( IS_VAR | IS_CV ) ) {
ZVAL_DEREF ( expr ) ;
}
2014-04-25 21:21:26 +08:00
/* 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-10-13 20:51:53 +08:00
FREE_OP1_IF_VAR ( ) ;
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 ) ;
}
2014-10-13 21:19:23 +08:00
} else {
2014-06-05 20:04:11 +08:00
if ( Z_OPT_REFCOUNTED_P ( expr ) ) Z_ADDREF_P ( expr ) ;
}
}
} else {
ZVAL_COPY_VALUE ( result , expr ) ;
2014-10-13 21:19:23 +08:00
Z_ADDREF_P ( result ) ;
2014-06-05 20:04:11 +08:00
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 ) ;
}
2014-10-13 21:19:23 +08:00
} else {
2014-06-05 20:04:11 +08:00
if ( Z_OPT_REFCOUNTED_P ( expr ) ) Z_ADDREF_P ( expr ) ;
}
}
} else {
ZVAL_COPY_VALUE ( result , expr ) ;
2014-10-13 21:19:23 +08:00
zval_opt_copy_ctor ( result ) ;
2014-06-05 20:04:11 +08:00
convert_to_object ( result ) ;
}
2014-04-25 21:21:26 +08:00
}
2004-10-23 05:42:14 +08:00
}
2014-10-13 21:19:23 +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 ( ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 73 , ZEND_INCLUDE_OR_EVAL , CONST | TMPVAR | 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
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-10-04 03:06:26 +08:00
ZVAL_STR ( & tmp_inc_filename , zval_get_string ( inc_filename ) ) ;
2014-02-10 14:04:30 +08:00
inc_filename = & tmp_inc_filename ;
2004-10-23 05:42:14 +08:00
}
2014-08-26 01:24:55 +08:00
if ( opline - > extended_value ! = ZEND_EVAL & & strlen ( Z_STRVAL_P ( inc_filename ) ) ! = Z_STRLEN_P ( inc_filename ) ) {
2011-06-07 05:28:16 +08:00
if ( opline - > extended_value = = ZEND_INCLUDE_ONCE | | opline - > extended_value = = ZEND_INCLUDE ) {
2014-12-14 06:06:14 +08:00
zend_message_dispatcher ( ZMSG_FAILED_INCLUDE_FOPEN , Z_STRVAL_P ( inc_filename ) ) ;
2011-06-07 05:28:16 +08:00
} else {
2014-12-14 06:06:14 +08:00
zend_message_dispatcher ( ZMSG_FAILED_REQUIRE_FOPEN , Z_STRVAL_P ( inc_filename ) ) ;
2011-06-07 05:28:16 +08:00
}
} else {
switch ( opline - > extended_value ) {
case ZEND_INCLUDE_ONCE :
case ZEND_REQUIRE_ONCE : {
zend_file_handle file_handle ;
2015-03-04 07:05:28 +08:00
zend_string * resolved_path ;
2011-06-07 05:28:16 +08:00
2014-12-14 06:06:14 +08:00
resolved_path = zend_resolve_path ( Z_STRVAL_P ( inc_filename ) , ( int ) Z_STRLEN_P ( inc_filename ) ) ;
2011-06-07 05:28:16 +08:00
if ( resolved_path ) {
2015-03-04 07:05:28 +08:00
failure_retval = zend_hash_exists ( & EG ( included_files ) , resolved_path ) ;
2011-06-07 05:28:16 +08:00
} else {
2015-03-04 07:05:28 +08:00
resolved_path = zend_string_copy ( Z_STR_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 */
2015-03-04 07:05:28 +08:00
} else if ( SUCCESS = = zend_stream_open ( resolved_path - > val , & file_handle ) ) {
2011-06-07 05:28:16 +08:00
if ( ! file_handle . opened_path ) {
2015-03-04 07:05:28 +08:00
file_handle . opened_path = zend_string_copy ( resolved_path ) ;
2011-06-07 05:28:16 +08:00
}
2015-03-04 07:05:28 +08:00
if ( zend_hash_add_empty_element ( & EG ( included_files ) , file_handle . opened_path ) ) {
2014-12-14 06:06:14 +08:00
new_op_array = zend_compile_file ( & file_handle , ( opline - > extended_value = = ZEND_INCLUDE_ONCE ? ZEND_INCLUDE : ZEND_REQUIRE ) ) ;
zend_destroy_file_handle ( & file_handle ) ;
2014-02-21 21:23:13 +08:00
} else {
2014-12-14 06:06:14 +08:00
zend_file_handle_dtor ( & file_handle ) ;
2014-02-21 21:23:13 +08:00
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 ) {
2014-12-14 06:06:14 +08:00
zend_message_dispatcher ( ZMSG_FAILED_INCLUDE_FOPEN , Z_STRVAL_P ( inc_filename ) ) ;
2011-06-07 05:28:16 +08:00
} else {
2014-12-14 06:06:14 +08:00
zend_message_dispatcher ( ZMSG_FAILED_REQUIRE_FOPEN , Z_STRVAL_P ( inc_filename ) ) ;
2011-06-07 05:28:16 +08:00
}
2004-10-23 05:42:14 +08:00
}
2015-03-04 07:05:28 +08:00
zend_string_release ( 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 :
2014-12-14 06:06:14 +08:00
new_op_array = compile_filename ( opline - > extended_value , inc_filename ) ;
2011-06-07 05:28:16 +08:00
break ;
case ZEND_EVAL : {
2014-12-14 06:06:14 +08:00
char * eval_desc = zend_make_compiled_string_description ( " eval()'d code " ) ;
2004-10-23 05:42:14 +08:00
2014-12-14 06:06:14 +08:00
new_op_array = zend_compile_string ( inc_filename , eval_desc ) ;
2011-06-07 05:28:16 +08:00
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 ) {
2014-11-25 06:22:59 +08:00
zend_string_release ( Z_STR ( 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
2015-03-25 06:57:05 +08:00
new_op_array - > scope = EG ( scope ) ;
2014-11-28 15:21:18 +08:00
2014-11-28 15:33:03 +08:00
call = zend_vm_stack_push_call_frame ( ZEND_CALL_NESTED_CODE ,
2014-12-14 06:06:14 +08:00
( zend_function * ) new_op_array , 0 , EX ( called_scope ) , Z_OBJ ( EX ( This ) ) , NULL ) ;
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-12-14 06:06:14 +08:00
call - > symbol_table = zend_rebuild_symbol_table ( ) ;
2008-04-29 16:15:20 +08:00
}
2014-07-07 19:50:44 +08:00
call - > prev_execute_data = execute_data ;
2014-12-14 06:06:14 +08:00
i_init_code_execute_data ( call , new_op_array , return_value ) ;
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-11-28 15:33:03 +08:00
ZEND_ADD_CALL_FLAG ( call , ZEND_CALL_TOP ) ;
2014-12-14 06:06:14 +08:00
zend_execute_ex ( call ) ;
2008-06-11 21:18:41 +08:00
}
2004-10-23 05:42:14 +08:00
2014-12-14 06:06:14 +08:00
destroy_op_array ( new_op_array ) ;
2014-08-28 00:49:56 +08:00
efree_size ( new_op_array , sizeof ( zend_op_array ) ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2014-12-14 06:06:14 +08:00
zend_throw_exception_internal ( NULL ) ;
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
}
2015-03-17 00:48:29 +08:00
ZEND_VM_INTERRUPT_CHECK ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 74 , ZEND_UNSET_VAR , CONST | TMPVAR | CV , UNUSED | CONST | VAR )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zval tmp , * varname ;
HashTable * target_symbol_table ;
zend_free_op free_op1 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2010-07-27 17:50:35 +08:00
if ( OP1_TYPE = = IS_CV & &
OP2_TYPE = = IS_UNUSED & &
( opline - > extended_value & ZEND_QUICK_SET ) ) {
2014-09-22 18:41:44 +08:00
zval * var = EX_VAR ( opline - > op1 . var ) ;
if ( Z_REFCOUNTED_P ( var ) ) {
zend_refcounted * garbage = Z_COUNTED_P ( var ) ;
if ( ! - - GC_REFCOUNT ( garbage ) ) {
ZVAL_UNDEF ( var ) ;
_zval_dtor_func_for_ptr ( garbage ZEND_FILE_LINE_CC ) ;
} else {
GC_ZVAL_CHECK_POSSIBLE_ROOT ( var ) ;
ZVAL_UNDEF ( var ) ;
}
} else {
ZVAL_UNDEF ( var ) ;
}
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 ) ;
2014-09-22 18:41:44 +08:00
ZVAL_UNDEF ( & tmp ) ;
2010-04-20 18:57:45 +08:00
if ( OP1_TYPE ! = IS_CONST & & Z_TYPE_P ( varname ) ! = IS_STRING ) {
2014-10-07 00:56:23 +08:00
ZVAL_STR ( & tmp , zval_get_string ( varname ) ) ;
2004-10-23 05:42:14 +08:00
varname = & tmp ;
}
2010-05-06 18:27:35 +08:00
if ( OP2_TYPE ! = IS_UNUSED ) {
zend_class_entry * ce ;
if ( OP2_TYPE = = IS_CONST ) {
2014-12-12 15:19:41 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ) {
ce = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-12-14 06:06:14 +08:00
ce = zend_fetch_class_by_name ( Z_STR_P ( EX_CONSTANT ( opline - > op2 ) ) , EX_CONSTANT ( opline - > op2 ) + 1 , 0 ) ;
2013-07-14 11:47:06 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2014-11-25 06:22:59 +08:00
if ( OP1_TYPE ! = IS_CONST & & Z_TYPE ( tmp ) ! = IS_UNDEF ) {
zend_string_release ( Z_STR ( 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 ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Class '%s' not found " , Z_STRVAL_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
if ( OP1_TYPE ! = IS_CONST ) {
zend_string_release ( Z_STR ( tmp ) ) ;
}
HANDLE_EXCEPTION ( ) ;
2012-02-25 21:56:59 +08:00
}
2014-12-12 15:19:41 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) , 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
}
2015-01-13 14:33:15 +08:00
zend_std_unset_static_property ( ce , Z_STR_P ( varname ) ) ;
2004-10-23 05:42:14 +08:00
} else {
2014-12-14 06:06:14 +08:00
target_symbol_table = zend_get_target_symbol_table ( execute_data , opline - > extended_value & ZEND_FETCH_TYPE_MASK ) ;
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-11-25 06:22:59 +08:00
if ( OP1_TYPE ! = IS_CONST & & Z_TYPE ( tmp ) ! = IS_UNDEF ) {
zend_string_release ( Z_STR ( 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 ( ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 75 , ZEND_UNSET_DIM , VAR | UNUSED | CV , CONST | TMPVAR | 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 ;
2014-08-26 01:24:55 +08:00
zend_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-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot unset string offsets " ) ;
FREE_UNFETCHED_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2014-09-08 19:46:45 +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-12-09 20:15:24 +08:00
ZEND_VM_C_LABEL ( unset_dim_again ) :
2014-10-10 20:36:12 +08:00
if ( OP1_TYPE ! = IS_UNUSED & & EXPECTED ( Z_TYPE_P ( container ) = = IS_ARRAY ) ) {
2014-12-09 20:15:24 +08:00
HashTable * ht ;
2014-03-26 22:07:31 +08:00
ZEND_VM_C_LABEL ( offset_again ) :
2014-12-09 20:15:24 +08:00
SEPARATE_ARRAY ( container ) ;
ht = Z_ARRVAL_P ( container ) ;
2014-10-10 20:36:12 +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-10-10 20:36:12 +08:00
zend_hash_index_del ( ht , hval ) ;
break ;
case IS_STRING :
if ( OP2_TYPE ! = IS_CONST ) {
if ( ZEND_HANDLE_NUMERIC ( Z_STR_P ( offset ) , hval ) ) {
ZEND_VM_C_GOTO ( num_index_dim ) ;
2014-04-04 23:01:53 +08:00
}
2014-10-10 20:36:12 +08:00
}
2015-02-14 03:20:39 +08:00
if ( ht = = & EG ( symbol_table ) ) {
2014-12-14 06:06:14 +08:00
zend_delete_global_variable ( Z_STR_P ( offset ) ) ;
2014-10-10 20:36:12 +08:00
} else {
zend_hash_del ( ht , Z_STR_P ( offset ) ) ;
}
break ;
case IS_NULL :
zend_hash_del ( ht , STR_EMPTY_ALLOC ( ) ) ;
break ;
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 ) ;
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 ;
2005-06-16 20:17:39 +08:00
}
2014-10-10 20:36:12 +08:00
} else if ( OP1_TYPE = = IS_UNUSED | | EXPECTED ( Z_TYPE_P ( container ) = = IS_OBJECT ) ) {
if ( UNEXPECTED ( Z_OBJ_HT_P ( container ) - > unset_dimension = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot use object as array " ) ;
} else {
Z_OBJ_HT_P ( container ) - > unset_dimension ( container , offset ) ;
}
2014-12-09 20:15:24 +08:00
} else if ( OP1_TYPE ! = IS_UNUSED & & Z_ISREF_P ( container ) ) {
container = Z_REFVAL_P ( container ) ;
ZEND_VM_C_GOTO ( unset_dim_again ) ;
} else if ( OP1_TYPE ! = IS_UNUSED & & UNEXPECTED ( Z_TYPE_P ( container ) = = IS_STRING ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot unset string offsets " ) ;
2005-06-16 20:17:39 +08:00
}
2015-03-09 20:57:15 +08:00
FREE_OP2 ( ) ;
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 ( ) ;
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 76 , ZEND_UNSET_OBJ , VAR | UNUSED | CV , CONST | TMPVAR | CV )
2005-06-16 20:17:39 +08:00
{
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-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( container = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot unset string offsets " ) ;
FREE_UNFETCHED_OP2 ( ) ;
FREE_OP1_VAR_PTR ( ) ;
HANDLE_EXCEPTION ( ) ;
2014-04-04 23:01:53 +08:00
}
2010-04-20 19:16:39 +08:00
offset = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2005-06-16 20:17:39 +08:00
2015-01-03 17:22:58 +08:00
do {
2014-12-09 06:09:44 +08:00
if ( OP1_TYPE ! = IS_UNUSED & & UNEXPECTED ( Z_TYPE_P ( container ) ! = IS_OBJECT ) ) {
if ( Z_ISREF_P ( container ) ) {
container = Z_REFVAL_P ( container ) ;
if ( Z_TYPE_P ( container ) ! = IS_OBJECT ) {
break ;
}
} else {
break ;
}
}
2014-04-04 23:01:53 +08:00
if ( Z_OBJ_HT_P ( container ) - > unset_property ) {
2015-02-25 06:52:35 +08:00
Z_OBJ_HT_P ( container ) - > unset_property ( container , offset , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( offset ) ) : NULL ) ) ;
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-12-09 06:09:44 +08:00
} while ( 0 ) ;
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 ( ) ;
}
2015-02-12 18:57:12 +08:00
ZEND_VM_HANDLER ( 77 , ZEND_FE_RESET_R , 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
zend_free_op free_op1 ;
2015-02-12 18:57:12 +08:00
zval * array_ptr , * result ;
2004-10-23 05:42:14 +08:00
HashTable * fe_ht ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2015-02-12 18:57:12 +08:00
array_ptr = GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ;
if ( EXPECTED ( Z_TYPE_P ( array_ptr ) = = IS_ARRAY ) ) {
result = EX_VAR ( opline - > result . var ) ;
ZVAL_COPY_VALUE ( result , array_ptr ) ;
if ( OP1_TYPE ! = IS_TMP_VAR & & Z_OPT_REFCOUNTED_P ( result ) ) {
Z_ADDREF_P ( array_ptr ) ;
}
Z_FE_POS_P ( result ) = 0 ;
FREE_OP1_IF_VAR ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( OP1_TYPE ! = IS_CONST & & EXPECTED ( Z_TYPE_P ( array_ptr ) = = IS_OBJECT ) ) {
if ( ! Z_OBJCE_P ( array_ptr ) - > get_iterator ) {
HashPosition pos = 0 ;
Bucket * p ;
result = EX_VAR ( opline - > result . var ) ;
ZVAL_COPY_VALUE ( result , array_ptr ) ;
if ( OP1_TYPE ! = IS_TMP_VAR ) {
2014-02-10 14:04:30 +08:00
Z_ADDREF_P ( array_ptr ) ;
2004-10-23 05:42:14 +08:00
}
2015-02-12 18:57:12 +08:00
fe_ht = Z_OBJPROP_P ( array_ptr ) ;
pos = 0 ;
while ( 1 ) {
if ( pos > = fe_ht - > nNumUsed ) {
FREE_OP1_IF_VAR ( ) ;
Z_FE_ITER_P ( EX_VAR ( opline - > result . var ) ) = ( uint32_t ) - 1 ;
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
}
p = fe_ht - > arData + pos ;
if ( ( Z_TYPE ( p - > val ) ! = IS_UNDEF & &
( Z_TYPE ( p - > val ) ! = IS_INDIRECT | |
Z_TYPE_P ( Z_INDIRECT ( p - > val ) ) ! = IS_UNDEF ) ) & &
( ! p - > key | |
zend_check_property_access ( Z_OBJ_P ( array_ptr ) , p - > key ) = = SUCCESS ) ) {
break ;
}
pos + + ;
}
Z_FE_ITER_P ( EX_VAR ( opline - > result . var ) ) = zend_hash_iterator_add ( fe_ht , pos ) ;
FREE_OP1_IF_VAR ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2004-10-23 05:42:14 +08:00
} else {
2015-02-12 18:57:12 +08:00
zend_class_entry * ce = Z_OBJCE_P ( array_ptr ) ;
zend_object_iterator * iter = ce - > get_iterator ( ce , array_ptr , 0 ) ;
zend_bool is_empty ;
if ( UNEXPECTED ( ! iter ) | | UNEXPECTED ( EG ( exception ) ) ) {
FREE_OP1 ( ) ;
if ( ! EG ( exception ) ) {
zend_throw_exception_ex ( NULL , 0 , " Object of type %s did not create an Iterator " , ce - > name - > val ) ;
2009-08-17 15:40:43 +08:00
}
2015-02-12 18:57:12 +08:00
zend_throw_exception_internal ( NULL ) ;
HANDLE_EXCEPTION ( ) ;
2009-08-17 15:40:43 +08:00
}
2015-02-12 18:57:12 +08:00
iter - > index = 0 ;
if ( iter - > funcs - > rewind ) {
iter - > funcs - > rewind ( iter ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
OBJ_RELEASE ( & iter - > std ) ;
FREE_OP1 ( ) ;
HANDLE_EXCEPTION ( ) ;
2013-05-17 17:15:09 +08:00
}
2006-10-03 17:05:14 +08:00
}
2015-02-12 18:57:12 +08:00
is_empty = iter - > funcs - > valid ( iter ) ! = SUCCESS ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
OBJ_RELEASE ( & iter - > std ) ;
FREE_OP1 ( ) ;
HANDLE_EXCEPTION ( ) ;
}
iter - > index = - 1 ; /* will be set to 0 before using next handler */
ZVAL_OBJ ( EX_VAR ( opline - > result . var ) , & iter - > std ) ;
Z_FE_ITER_P ( EX_VAR ( opline - > result . var ) ) = ( uint32_t ) - 1 ;
FREE_OP1 ( ) ;
if ( is_empty ) {
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2014-05-29 22:21:56 +08:00
} else {
2015-02-12 18:57:12 +08:00
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2013-05-17 17:15:09 +08:00
}
2004-10-23 05:42:14 +08:00
}
2015-02-12 18:57:12 +08:00
} else {
zend_error ( E_WARNING , " Invalid argument supplied for foreach() " ) ;
ZVAL_UNDEF ( EX_VAR ( opline - > result . var ) ) ;
Z_FE_ITER_P ( EX_VAR ( opline - > result . var ) ) = ( uint32_t ) - 1 ;
FREE_OP1 ( ) ;
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2004-10-23 05:42:14 +08:00
}
2015-02-12 18:57:12 +08:00
}
2004-10-23 05:42:14 +08:00
2015-02-12 18:57:12 +08:00
ZEND_VM_HANDLER ( 125 , ZEND_FE_RESET_RW , CONST | TMP | VAR | CV , ANY )
{
USE_OPLINE
zend_free_op free_op1 ;
zval * array_ptr , * array_ref ;
HashTable * fe_ht ;
HashPosition pos = 0 ;
Bucket * p ;
2004-10-23 05:42:14 +08:00
2015-02-12 18:57:12 +08:00
SAVE_OPLINE ( ) ;
2004-10-23 05:42:14 +08:00
2015-02-12 18:57:12 +08:00
if ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) {
array_ref = array_ptr = GET_OP1_ZVAL_PTR_PTR ( BP_VAR_R ) ;
if ( Z_ISREF_P ( array_ref ) ) {
array_ptr = Z_REFVAL_P ( array_ref ) ;
2013-05-17 17:15:09 +08:00
}
2015-02-12 18:57:12 +08:00
} else {
array_ref = array_ptr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
}
if ( EXPECTED ( Z_TYPE_P ( array_ptr ) = = IS_ARRAY ) ) {
if ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) {
if ( array_ptr = = array_ref ) {
ZVAL_NEW_REF ( array_ref , array_ref ) ;
array_ptr = Z_REFVAL_P ( array_ref ) ;
}
Z_ADDREF_P ( array_ref ) ;
ZVAL_COPY_VALUE ( EX_VAR ( opline - > result . var ) , array_ref ) ;
2004-10-23 05:42:14 +08:00
} else {
2015-02-12 18:57:12 +08:00
array_ptr = EX_VAR ( opline - > result . var ) ;
ZVAL_COPY_VALUE ( array_ptr , array_ref ) ;
2013-05-17 17:15:09 +08:00
}
2015-02-12 18:57:12 +08:00
if ( OP1_TYPE = = IS_CONST ) {
zval_copy_ctor_func ( array_ptr ) ;
2004-10-23 05:42:14 +08:00
} else {
2015-02-12 18:57:12 +08:00
SEPARATE_ARRAY ( array_ptr ) ;
}
fe_ht = Z_ARRVAL_P ( array_ptr ) ;
while ( 1 ) {
if ( pos > = fe_ht - > nNumUsed ) {
2013-05-17 17:15:09 +08:00
FREE_OP1_VAR_PTR ( ) ;
2015-02-12 18:57:12 +08:00
Z_FE_ITER_P ( EX_VAR ( opline - > result . var ) ) = ( uint32_t ) - 1 ;
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2013-05-17 17:15:09 +08:00
}
2015-02-12 18:57:12 +08:00
p = fe_ht - > arData + pos ;
if ( Z_TYPE ( p - > val ) ! = IS_UNDEF & &
( Z_TYPE ( p - > val ) ! = IS_INDIRECT | |
Z_TYPE_P ( Z_INDIRECT ( p - > val ) ) ! = IS_UNDEF ) ) {
break ;
2005-01-25 18:40:51 +08:00
}
2015-02-12 18:57:12 +08:00
pos + + ;
2004-10-23 05:42:14 +08:00
}
2015-02-12 18:57:12 +08:00
Z_FE_ITER_P ( EX_VAR ( opline - > result . var ) ) = zend_hash_iterator_add ( fe_ht , pos ) ;
2004-10-23 05:42:14 +08:00
2015-02-12 18:57:12 +08:00
FREE_OP1_VAR_PTR ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( OP1_TYPE ! = IS_CONST & & EXPECTED ( Z_TYPE_P ( array_ptr ) = = IS_OBJECT ) ) {
if ( ! Z_OBJCE_P ( array_ptr ) - > get_iterator ) {
if ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) {
if ( array_ptr = = array_ref ) {
ZVAL_NEW_REF ( array_ref , array_ref ) ;
array_ptr = Z_REFVAL_P ( array_ref ) ;
}
Z_ADDREF_P ( array_ref ) ;
ZVAL_COPY_VALUE ( EX_VAR ( opline - > result . var ) , array_ref ) ;
} else {
array_ptr = EX_VAR ( opline - > result . var ) ;
ZVAL_COPY_VALUE ( array_ptr , array_ref ) ;
}
fe_ht = Z_OBJPROP_P ( array_ptr ) ;
while ( 1 ) {
if ( pos > = fe_ht - > nNumUsed ) {
FREE_OP1_VAR_PTR ( ) ;
Z_FE_ITER_P ( EX_VAR ( opline - > result . var ) ) = ( uint32_t ) - 1 ;
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
}
p = fe_ht - > arData + pos ;
if ( ( Z_TYPE ( p - > val ) ! = IS_UNDEF & &
( Z_TYPE ( p - > val ) ! = IS_INDIRECT | |
Z_TYPE_P ( Z_INDIRECT ( p - > val ) ) ! = IS_UNDEF ) ) & &
( ! p - > key | |
zend_check_property_access ( Z_OBJ_P ( array_ptr ) , p - > key ) = = SUCCESS ) ) {
break ;
}
pos + + ;
}
Z_FE_ITER_P ( EX_VAR ( opline - > result . var ) ) = zend_hash_iterator_add ( fe_ht , pos ) ;
2004-10-23 05:42:14 +08:00
2015-02-12 18:57:12 +08:00
FREE_OP1_VAR_PTR ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else {
zend_class_entry * ce = Z_OBJCE_P ( array_ptr ) ;
zend_object_iterator * iter = ce - > get_iterator ( ce , array_ptr , 1 ) ;
zend_bool is_empty ;
if ( UNEXPECTED ( ! iter ) | | UNEXPECTED ( EG ( exception ) ) ) {
if ( OP1_TYPE = = IS_VAR ) {
FREE_OP1_VAR_PTR ( ) ;
} else {
FREE_OP1 ( ) ;
}
if ( ! EG ( exception ) ) {
zend_throw_exception_ex ( NULL , 0 , " Object of type %s did not create an Iterator " , ce - > name - > val ) ;
}
zend_throw_exception_internal ( NULL ) ;
HANDLE_EXCEPTION ( ) ;
}
iter - > index = 0 ;
if ( iter - > funcs - > rewind ) {
iter - > funcs - > rewind ( iter ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
OBJ_RELEASE ( & iter - > std ) ;
if ( OP1_TYPE = = IS_VAR ) {
FREE_OP1_VAR_PTR ( ) ;
} else {
FREE_OP1 ( ) ;
}
HANDLE_EXCEPTION ( ) ;
}
}
is_empty = iter - > funcs - > valid ( iter ) ! = SUCCESS ;
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2015-02-12 18:57:12 +08:00
OBJ_RELEASE ( & iter - > std ) ;
if ( OP1_TYPE = = IS_VAR ) {
2013-05-17 17:15:09 +08:00
FREE_OP1_VAR_PTR ( ) ;
2015-02-12 18:57:12 +08:00
} else {
FREE_OP1 ( ) ;
2013-05-17 17:15:09 +08:00
}
2010-04-20 19:16:39 +08:00
HANDLE_EXCEPTION ( ) ;
2005-04-27 14:47:08 +08:00
}
2015-02-12 18:57:12 +08:00
iter - > index = - 1 ; /* will be set to 0 before using next handler */
ZVAL_OBJ ( EX_VAR ( opline - > result . var ) , & iter - > std ) ;
Z_FE_ITER_P ( EX_VAR ( opline - > result . var ) ) = ( uint32_t ) - 1 ;
if ( OP1_TYPE = = IS_VAR ) {
2013-05-17 17:15:09 +08:00
FREE_OP1_VAR_PTR ( ) ;
2015-02-12 18:57:12 +08:00
} else {
FREE_OP1 ( ) ;
}
if ( is_empty ) {
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
} else {
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2013-05-17 17:15:09 +08:00
}
2005-04-27 14:47:08 +08:00
}
2015-02-12 18:57:12 +08:00
} else {
zend_error ( E_WARNING , " Invalid argument supplied for foreach() " ) ;
ZVAL_UNDEF ( EX_VAR ( opline - > result . var ) ) ;
Z_FE_ITER_P ( EX_VAR ( opline - > result . var ) ) = ( uint32_t ) - 1 ;
if ( OP1_TYPE = = IS_VAR ) {
FREE_OP1_VAR_PTR ( ) ;
} else {
FREE_OP1 ( ) ;
}
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
}
}
ZEND_VM_HANDLER ( 78 , ZEND_FE_FETCH_R , VAR , ANY )
{
USE_OPLINE
zval * array ;
zval * value ;
HashTable * fe_ht ;
HashPosition pos ;
Bucket * p ;
2014-09-16 05:34:27 +08:00
2015-02-12 18:57:12 +08:00
array = EX_VAR ( opline - > op1 . var ) ;
SAVE_OPLINE ( ) ;
if ( EXPECTED ( Z_TYPE_P ( array ) = = IS_ARRAY ) ) {
fe_ht = Z_ARRVAL_P ( array ) ;
pos = Z_FE_POS_P ( EX_VAR ( opline - > op1 . var ) ) ;
2014-09-16 05:34:27 +08:00
while ( 1 ) {
2015-02-12 18:57:12 +08:00
if ( UNEXPECTED ( pos > = fe_ht - > nNumUsed ) ) {
/* reached end of iteration */
2014-12-12 15:19:41 +08:00
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2005-02-05 22:01:59 +08:00
}
2014-09-16 05:34:27 +08:00
p = fe_ht - > arData + pos ;
2015-02-12 18:57:12 +08:00
value = & p - > val ;
if ( Z_TYPE_P ( value ) = = IS_UNDEF ) {
2014-09-16 05:34:27 +08:00
pos + + ;
continue ;
2015-02-12 18:57:12 +08:00
} else if ( Z_TYPE_P ( value ) = = IS_INDIRECT ) {
value = Z_INDIRECT_P ( value ) ;
if ( Z_TYPE_P ( value ) = = IS_UNDEF ) {
pos + + ;
continue ;
}
2014-09-16 05:34:27 +08:00
}
2015-02-12 18:57:12 +08:00
break ;
}
if ( opline - > extended_value ) {
if ( ! p - > key ) {
ZVAL_LONG ( EX_VAR ( ( opline + 1 ) - > result . var ) , p - > h ) ;
} else {
ZVAL_STR_COPY ( EX_VAR ( ( opline + 1 ) - > result . var ) , p - > key ) ;
2014-09-16 05:34:27 +08:00
}
2005-02-05 22:01:59 +08:00
}
2015-02-12 18:57:12 +08:00
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , value ) ;
Z_FE_POS_P ( EX_VAR ( opline - > op1 . var ) ) = pos + 1 ;
ZEND_VM_INC_OPCODE ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( array ) = = IS_OBJECT ) ) {
zend_object_iterator * iter ;
if ( ( iter = zend_iterator_unwrap ( array ) ) = = NULL ) {
/* plain object */
fe_ht = Z_OBJPROP_P ( array ) ;
pos = zend_hash_iterator_pos ( Z_FE_ITER_P ( EX_VAR ( opline - > op1 . var ) ) , fe_ht ) ;
while ( 1 ) {
if ( UNEXPECTED ( pos > = fe_ht - > nNumUsed ) ) {
/* reached end of iteration */
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
}
p = fe_ht - > arData + pos ;
value = & p - > val ;
if ( Z_TYPE_P ( value ) = = IS_UNDEF ) {
pos + + ;
continue ;
} else if ( Z_TYPE_P ( value ) = = IS_INDIRECT ) {
value = Z_INDIRECT_P ( value ) ;
if ( Z_TYPE_P ( value ) = = IS_UNDEF ) {
pos + + ;
continue ;
}
}
if ( ! p - > key | |
zend_check_property_access ( Z_OBJ_P ( array ) , p - > key ) = = SUCCESS ) {
break ;
}
pos + + ;
}
if ( opline - > extended_value ) {
if ( UNEXPECTED ( ! p - > key ) ) {
ZVAL_LONG ( EX_VAR ( ( opline + 1 ) - > result . var ) , p - > h ) ;
} else if ( p - > key - > val [ 0 ] ) {
ZVAL_STR_COPY ( EX_VAR ( ( opline + 1 ) - > result . var ) , p - > key ) ;
} else {
const char * class_name , * prop_name ;
size_t prop_name_len ;
zend_unmangle_property_name_ex (
p - > key , & class_name , & prop_name , & prop_name_len ) ;
ZVAL_STRINGL ( EX_VAR ( ( opline + 1 ) - > result . var ) , prop_name , prop_name_len ) ;
}
}
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , value ) ;
while ( 1 ) {
pos + + ;
if ( pos > = fe_ht - > nNumUsed ) {
2015-03-13 22:13:19 +08:00
pos = HT_INVALID_IDX ;
2015-02-12 18:57:12 +08:00
break ;
}
p = fe_ht - > arData + pos ;
if ( ( Z_TYPE ( p - > val ) ! = IS_UNDEF & &
( Z_TYPE ( p - > val ) ! = IS_INDIRECT | |
Z_TYPE_P ( Z_INDIRECT ( p - > val ) ) ! = IS_UNDEF ) ) & &
( Z_TYPE_P ( array ) ! = IS_OBJECT | |
! p - > key | |
zend_check_property_access ( Z_OBJ_P ( array ) , p - > key ) = = SUCCESS ) ) {
break ;
}
}
2015-02-12 19:36:04 +08:00
EG ( ht_iterators ) [ Z_FE_ITER_P ( EX_VAR ( opline - > op1 . var ) ) ] . pos = pos ;
2015-02-12 18:57:12 +08:00
ZEND_VM_INC_OPCODE ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else {
/* !iter happens from exception */
if ( iter & & + + iter - > index > 0 ) {
/* 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 ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
zval_ptr_dtor ( array ) ;
HANDLE_EXCEPTION ( ) ;
}
}
/* If index is zero we come from FE_RESET and checked valid() already. */
if ( ! iter | | ( iter - > index > 0 & & iter - > funcs - > valid ( iter ) = = FAILURE ) ) {
/* reached end of iteration */
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
zval_ptr_dtor ( array ) ;
HANDLE_EXCEPTION ( ) ;
}
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
}
value = iter - > funcs - > get_current_data ( iter ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
zval_ptr_dtor ( array ) ;
HANDLE_EXCEPTION ( ) ;
}
if ( ! value ) {
/* failure in get_current_data */
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
}
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , value ) ;
if ( opline - > extended_value ) {
if ( iter - > funcs - > get_current_key ) {
iter - > funcs - > get_current_key ( iter , EX_VAR ( ( opline + 1 ) - > result . var ) ) ;
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
zval_ptr_dtor ( array ) ;
HANDLE_EXCEPTION ( ) ;
}
} else {
ZVAL_LONG ( EX_VAR ( ( opline + 1 ) - > result . var ) , iter - > index ) ;
}
}
ZEND_VM_INC_OPCODE ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
} else {
zend_error ( E_WARNING , " Invalid argument supplied for foreach() " ) ;
2014-12-12 15:19:41 +08:00
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2005-02-05 22:01:59 +08:00
}
2004-10-23 05:42:14 +08:00
}
2015-02-12 18:57:12 +08:00
ZEND_VM_HANDLER ( 126 , ZEND_FE_FETCH_RW , VAR , ANY )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2015-02-12 18:57:12 +08:00
zval * array ;
2014-02-10 14:04:30 +08:00
zval * value ;
2004-10-23 05:42:14 +08:00
HashTable * fe_ht ;
2014-09-16 05:34:27 +08:00
HashPosition pos ;
Bucket * p ;
2014-03-06 03:22:50 +08:00
2015-02-12 18:57:12 +08:00
array = EX_VAR ( opline - > op1 . var ) ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2015-02-12 18:57:12 +08:00
ZVAL_DEREF ( array ) ;
2014-09-16 05:34:27 +08:00
if ( EXPECTED ( Z_TYPE_P ( array ) = = IS_ARRAY ) ) {
fe_ht = Z_ARRVAL_P ( array ) ;
2015-02-12 18:57:12 +08:00
pos = zend_hash_iterator_pos ( Z_FE_ITER_P ( EX_VAR ( opline - > op1 . var ) ) , fe_ht ) ;
2014-09-16 05:34:27 +08:00
while ( 1 ) {
if ( UNEXPECTED ( pos > = fe_ht - > nNumUsed ) ) {
/* reached end of iteration */
2014-12-12 15:19:41 +08:00
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2014-09-16 05:34:27 +08:00
}
p = fe_ht - > arData + pos ;
value = & p - > val ;
2015-02-12 18:57:12 +08:00
if ( Z_TYPE_P ( value ) = = IS_UNDEF ) {
2014-09-16 05:34:27 +08:00
pos + + ;
continue ;
2015-02-12 18:57:12 +08:00
} else if ( Z_TYPE_P ( value ) = = IS_INDIRECT ) {
2014-09-16 05:34:27 +08:00
value = Z_INDIRECT_P ( value ) ;
2015-02-12 18:57:12 +08:00
if ( Z_TYPE_P ( value ) = = IS_UNDEF ) {
2014-09-16 05:34:27 +08:00
pos + + ;
continue ;
}
}
2015-02-12 18:57:12 +08:00
break ;
}
if ( opline - > extended_value ) {
if ( ! p - > key ) {
ZVAL_LONG ( EX_VAR ( ( opline + 1 ) - > result . var ) , p - > h ) ;
2014-09-16 05:34:27 +08:00
} else {
2015-02-12 18:57:12 +08:00
ZVAL_STR_COPY ( EX_VAR ( ( opline + 1 ) - > result . var ) , p - > key ) ;
2014-09-16 05:34:27 +08:00
}
}
2015-02-12 18:57:12 +08:00
ZVAL_MAKE_REF ( value ) ;
Z_ADDREF_P ( value ) ;
ZVAL_REF ( EX_VAR ( opline - > result . var ) , Z_REF_P ( value ) ) ;
while ( 1 ) {
2014-09-16 05:34:27 +08:00
pos + + ;
if ( pos > = fe_ht - > nNumUsed ) {
2015-03-13 22:13:19 +08:00
pos = HT_INVALID_IDX ;
2015-02-12 18:57:12 +08:00
break ;
2014-09-16 05:34:27 +08:00
}
p = fe_ht - > arData + pos ;
2015-02-12 18:57:12 +08:00
if ( Z_TYPE ( p - > val ) ! = IS_UNDEF & &
( Z_TYPE ( p - > val ) ! = IS_INDIRECT | |
Z_TYPE_P ( Z_INDIRECT ( p - > val ) ) ! = IS_UNDEF ) ) {
break ;
}
}
2015-02-12 19:36:04 +08:00
EG ( ht_iterators ) [ Z_FE_ITER_P ( EX_VAR ( opline - > op1 . var ) ) ] . pos = pos ;
2014-09-16 05:34:27 +08:00
ZEND_VM_INC_OPCODE ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else if ( EXPECTED ( Z_TYPE_P ( array ) = = IS_OBJECT ) ) {
zend_object_iterator * iter ;
2015-01-03 17:22:58 +08:00
2014-12-14 06:06:14 +08:00
if ( ( iter = zend_iterator_unwrap ( array ) ) = = NULL ) {
2014-09-16 05:34:27 +08:00
/* plain object */
2015-01-03 17:22:58 +08:00
2014-09-16 05:34:27 +08:00
fe_ht = Z_OBJPROP_P ( array ) ;
2015-02-12 18:57:12 +08:00
pos = zend_hash_iterator_pos ( Z_FE_ITER_P ( EX_VAR ( opline - > op1 . var ) ) , fe_ht ) ;
2014-03-26 22:07:31 +08:00
while ( 1 ) {
2014-09-16 05:34:27 +08:00
if ( UNEXPECTED ( pos > = fe_ht - > nNumUsed ) ) {
2004-10-23 05:42:14 +08:00
/* reached end of iteration */
2014-12-12 15:19:41 +08:00
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2004-10-23 05:42:14 +08:00
}
2014-03-26 22:07:31 +08:00
2014-09-16 05:34:27 +08:00
p = fe_ht - > arData + pos ;
value = & p - > val ;
2015-02-12 18:57:12 +08:00
if ( Z_TYPE_P ( value ) = = IS_UNDEF ) {
2014-09-16 05:34:27 +08:00
pos + + ;
continue ;
2015-02-12 18:57:12 +08:00
} else if ( Z_TYPE_P ( value ) = = IS_INDIRECT ) {
2014-03-26 22:07:31 +08:00
value = Z_INDIRECT_P ( value ) ;
2015-02-12 18:57:12 +08:00
if ( Z_TYPE_P ( value ) = = IS_UNDEF ) {
2014-09-16 05:34:27 +08:00
pos + + ;
2014-03-26 22:07:31 +08:00
continue ;
}
}
2015-02-12 18:57:12 +08:00
if ( ! p - > key | |
zend_check_property_access ( Z_OBJ_P ( array ) , p - > key ) = = SUCCESS ) {
2014-03-26 22:07:31 +08:00
break ;
}
2014-09-16 05:34:27 +08:00
pos + + ;
2014-03-26 22:07:31 +08:00
}
2015-02-12 18:57:12 +08:00
if ( opline - > extended_value ) {
if ( UNEXPECTED ( ! p - > key ) ) {
ZVAL_LONG ( EX_VAR ( ( opline + 1 ) - > result . var ) , p - > h ) ;
} else if ( p - > key - > val [ 0 ] ) {
ZVAL_STR_COPY ( EX_VAR ( ( opline + 1 ) - > result . var ) , p - > key ) ;
} else {
const char * class_name , * prop_name ;
size_t prop_name_len ;
zend_unmangle_property_name_ex (
p - > key , & class_name , & prop_name , & prop_name_len ) ;
ZVAL_STRINGL ( EX_VAR ( ( opline + 1 ) - > result . var ) , prop_name , prop_name_len ) ;
}
2004-10-23 05:42:14 +08:00
}
2015-02-12 18:57:12 +08:00
ZVAL_MAKE_REF ( value ) ;
Z_ADDREF_P ( value ) ;
ZVAL_REF ( EX_VAR ( opline - > result . var ) , Z_REF_P ( value ) ) ;
while ( 1 ) {
2014-09-16 05:34:27 +08:00
pos + + ;
if ( pos > = fe_ht - > nNumUsed ) {
2015-03-13 22:13:19 +08:00
pos = HT_INVALID_IDX ;
2015-02-12 18:57:12 +08:00
break ;
2014-09-16 05:34:27 +08:00
}
p = fe_ht - > arData + pos ;
2015-02-12 18:57:12 +08:00
if ( ( Z_TYPE ( p - > val ) ! = IS_UNDEF & &
( Z_TYPE ( p - > val ) ! = IS_INDIRECT | |
Z_TYPE_P ( Z_INDIRECT ( p - > val ) ) ! = IS_UNDEF ) ) & &
( Z_TYPE_P ( array ) ! = IS_OBJECT | |
! p - > key | |
zend_check_property_access ( Z_OBJ_P ( array ) , p - > key ) = = SUCCESS ) ) {
break ;
}
}
2015-02-12 19:36:04 +08:00
EG ( ht_iterators ) [ Z_FE_ITER_P ( EX_VAR ( opline - > op1 . var ) ) ] . pos = pos ;
2014-09-16 05:34:27 +08:00
ZEND_VM_INC_OPCODE ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
} else {
2004-10-23 05:42:14 +08:00
/* !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 . */
2014-12-14 06:06:14 +08:00
iter - > funcs - > move_forward ( iter ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2015-02-12 18:57:12 +08:00
zval_ptr_dtor ( array ) ;
2010-04-20 19:16:39 +08:00
HANDLE_EXCEPTION ( ) ;
2005-04-27 14:47:08 +08:00
}
2004-10-23 05:42:14 +08:00
}
2006-05-12 05:07:39 +08:00
/* If index is zero we come from FE_RESET and checked valid() already. */
2014-12-14 06:06:14 +08:00
if ( ! iter | | ( iter - > index > 0 & & iter - > funcs - > valid ( iter ) = = 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 ) ) {
2015-02-12 18:57:12 +08:00
zval_ptr_dtor ( array ) ;
2010-04-20 19:16:39 +08:00
HANDLE_EXCEPTION ( ) ;
2005-04-27 14:47:08 +08:00
}
2014-12-12 15:19:41 +08:00
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2004-10-23 05:42:14 +08:00
}
2014-12-14 06:06:14 +08:00
value = iter - > funcs - > get_current_data ( iter ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2015-02-12 18:57:12 +08:00
zval_ptr_dtor ( array ) ;
2010-04-20 19:16:39 +08:00
HANDLE_EXCEPTION ( ) ;
2005-06-06 16:24:05 +08:00
}
2004-10-23 05:42:14 +08:00
if ( ! value ) {
/* failure in get_current_data */
2014-12-12 15:19:41 +08:00
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2004-10-23 05:42:14 +08:00
}
2015-02-12 18:57:12 +08:00
if ( opline - > extended_value ) {
2004-10-23 05:42:14 +08:00
if ( iter - > funcs - > get_current_key ) {
2014-12-14 06:06:14 +08:00
iter - > funcs - > get_current_key ( iter , EX_VAR ( ( opline + 1 ) - > result . var ) ) ;
2010-04-20 19:16:39 +08:00
if ( UNEXPECTED ( EG ( exception ) ! = NULL ) ) {
2015-02-12 18:57:12 +08:00
zval_ptr_dtor ( array ) ;
2010-04-20 19:16:39 +08:00
HANDLE_EXCEPTION ( ) ;
2005-04-27 14:47:08 +08:00
}
2004-10-23 05:42:14 +08:00
} else {
2014-09-16 05:34:27 +08:00
ZVAL_LONG ( EX_VAR ( ( opline + 1 ) - > result . var ) , iter - > index ) ;
2004-10-23 05:42:14 +08:00
}
}
2015-02-12 18:57:12 +08:00
ZVAL_MAKE_REF ( value ) ;
Z_ADDREF_P ( value ) ;
ZVAL_REF ( EX_VAR ( opline - > result . var ) , Z_REF_P ( value ) ) ;
2014-09-16 05:34:27 +08:00
ZEND_VM_INC_OPCODE ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-06-05 20:04:11 +08:00
} else {
2014-09-16 05:34:27 +08:00
zend_error ( E_WARNING , " Invalid argument supplied for foreach() " ) ;
2014-12-12 15:19:41 +08:00
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2005-02-08 00:09:54 +08:00
}
2004-10-23 05:42:14 +08:00
}
2014-12-05 17:40:47 +08:00
ZEND_VM_HANDLER ( 114 , ZEND_ISSET_ISEMPTY_VAR , CONST | TMPVAR | 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
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-10-17 04:17:13 +08:00
value = EX_VAR ( opline - > op1 . var ) ;
2015-01-03 17:22:58 +08:00
if ( opline - > extended_value & ZEND_ISSET ) {
2014-10-17 04:17:13 +08:00
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) ,
Z_TYPE_P ( value ) > IS_NULL & &
( ! Z_ISREF_P ( value ) | | Z_TYPE_P ( Z_REFVAL_P ( value ) ) ! = IS_NULL ) ) ;
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) ,
2014-12-14 06:06:14 +08:00
! i_zend_is_true ( value ) ) ;
2014-10-17 04:17:13 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
}
2014-10-17 04:17:13 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
2004-10-23 05:42:14 +08:00
} else {
2008-04-29 16:15:20 +08:00
zend_free_op free_op1 ;
zval tmp , * varname = GET_OP1_ZVAL_PTR ( BP_VAR_IS ) ;
2014-11-25 06:22:59 +08:00
ZVAL_UNDEF ( & tmp ) ;
2010-04-20 18:57:45 +08:00
if ( OP1_TYPE ! = IS_CONST & & Z_TYPE_P ( varname ) ! = IS_STRING ) {
2014-10-07 00:56:23 +08:00
ZVAL_STR ( & tmp , zval_get_string ( varname ) ) ;
2008-04-29 16:15:20 +08:00
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 ) {
2015-01-13 14:33:15 +08:00
if ( OP1_TYPE = = IS_CONST & & CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) ) ) {
ce = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) ) ;
2015-02-25 06:52:35 +08:00
value = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) + sizeof ( void * ) ) ;
2015-01-13 14:33:15 +08:00
/* check if static properties were destoyed */
if ( UNEXPECTED ( CE_STATIC_MEMBERS ( ce ) = = NULL ) ) {
zend_error_noreturn ( E_ERROR , " Access to undeclared static property: %s::$%s " , ce - > name - > val , Z_STR_P ( varname ) ) ;
}
ZEND_VM_C_GOTO ( is_var_return ) ;
} else if ( CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ) {
2014-12-12 15:19:41 +08:00
ce = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-12-14 06:06:14 +08:00
ce = zend_fetch_class_by_name ( Z_STR_P ( EX_CONSTANT ( opline - > op2 ) ) , EX_CONSTANT ( opline - > op2 ) + 1 , 0 ) ;
2012-02-25 21:56:59 +08:00
if ( UNEXPECTED ( ce = = NULL ) ) {
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-12-12 15:19:41 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) , 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 ) ) ;
2015-01-13 14:33:15 +08:00
if ( OP1_TYPE = = IS_CONST & &
( value = CACHED_POLYMORPHIC_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) , ce ) ) ! = NULL ) {
/* check if static properties were destoyed */
if ( UNEXPECTED ( CE_STATIC_MEMBERS ( ce ) = = NULL ) ) {
zend_error_noreturn ( E_ERROR , " Access to undeclared static property: %s::$%s " , ce - > name - > val , Z_STR_P ( varname ) ) ;
}
ZEND_VM_C_GOTO ( is_var_return ) ;
}
2010-05-06 18:27:35 +08:00
}
2015-01-13 14:33:15 +08:00
value = zend_std_get_static_property ( ce , Z_STR_P ( varname ) , 1 ) ;
if ( OP1_TYPE = = IS_CONST & & value ) {
CACHE_POLYMORPHIC_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) , ce , value ) ;
}
2008-04-29 16:15:20 +08:00
} else {
2014-12-14 06:06:14 +08:00
HashTable * target_symbol_table = zend_get_target_symbol_table ( execute_data , opline - > extended_value & ZEND_FETCH_TYPE_MASK ) ;
2014-10-07 02:38:05 +08:00
value = zend_hash_find_ind ( target_symbol_table , Z_STR_P ( varname ) ) ;
2008-04-29 16:15:20 +08:00
}
2014-11-25 06:22:59 +08:00
if ( OP1_TYPE ! = IS_CONST & & Z_TYPE ( tmp ) ! = IS_UNDEF ) {
zend_string_release ( Z_STR ( tmp ) ) ;
2008-04-29 16:15:20 +08:00
}
FREE_OP1 ( ) ;
2004-10-23 05:42:14 +08:00
2015-01-13 14:33:15 +08:00
ZEND_VM_C_LABEL ( is_var_return ) :
2015-01-03 17:22:58 +08:00
if ( opline - > extended_value & ZEND_ISSET ) {
2014-10-17 04:17:13 +08:00
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) ,
value & & Z_TYPE_P ( value ) > IS_NULL & &
( ! Z_ISREF_P ( value ) | | Z_TYPE_P ( Z_REFVAL_P ( value ) ) ! = IS_NULL ) ) ;
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) ,
2014-12-14 06:06:14 +08:00
! value | | ! i_zend_is_true ( value ) ) ;
2010-04-20 18:57:45 +08:00
}
2004-10-23 05:42:14 +08:00
2014-10-17 04:17:13 +08:00
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2004-10-23 05:42:14 +08:00
}
2014-12-08 23:11:14 +08:00
ZEND_VM_HANDLER ( 115 , ZEND_ISSET_ISEMPTY_DIM_OBJ , CONST | TMPVAR | UNUSED | CV , CONST | TMPVAR | 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 ;
2014-08-26 01:24:55 +08:00
zend_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-12-08 23:11:14 +08:00
container = GET_OP1_OBJ_ZVAL_PTR ( 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-12-08 23:11:14 +08:00
ZEND_VM_C_LABEL ( isset_dim_obj_again ) :
2014-10-17 04:17:13 +08:00
if ( OP1_TYPE ! = IS_UNUSED & & EXPECTED ( 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 ) ;
2014-08-26 01:24:55 +08:00
} else if ( EXPECTED ( Z_TYPE_P ( offset ) = = IS_LONG ) ) {
hval = Z_LVAL_P ( offset ) ;
2014-06-05 22:42:17 +08:00
ZEND_VM_C_LABEL ( num_index_prop ) :
value = zend_hash_index_find ( ht , hval ) ;
} else {
switch ( Z_TYPE_P ( offset ) ) {
case IS_DOUBLE :
2014-08-26 01:24:55 +08:00
hval = zend_dval_to_lval ( Z_DVAL_P ( offset ) ) ;
2014-06-05 22:42:17 +08:00
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 :
2014-07-22 22:40:29 +08:00
hval = 1 ;
2014-06-05 22:42:17 +08:00
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 */
2014-08-15 02:44:25 +08:00
result = value ! = NULL & & Z_TYPE_P ( value ) > IS_NULL & &
( ! Z_ISREF_P ( value ) | | Z_TYPE_P ( Z_REFVAL_P ( value ) ) ! = IS_NULL ) ;
2010-07-16 19:44:30 +08:00
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
2014-12-14 06:06:14 +08:00
result = ( value = = NULL | | ! i_zend_is_true ( value ) ) ;
2010-07-16 19:44:30 +08:00
}
2014-10-17 04:17:13 +08:00
} else if ( OP1_TYPE = = IS_UNUSED | | EXPECTED ( Z_TYPE_P ( container ) = = IS_OBJECT ) ) {
if ( EXPECTED ( Z_OBJ_HT_P ( container ) - > has_dimension ) ) {
2014-12-14 06:06:14 +08:00
result = Z_OBJ_HT_P ( container ) - > has_dimension ( container , offset , ( opline - > extended_value & ZEND_ISSET ) = = 0 ) ;
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-10-17 04:17:13 +08:00
} else if ( EXPECTED ( 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 ;
2014-08-26 01:24:55 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( offset ) ! = IS_LONG ) ) {
2014-12-05 17:40:47 +08:00
if ( OP2_TYPE & ( IS_CV | IS_VAR ) ) {
2014-07-29 19:29:22 +08:00
ZVAL_DEREF ( offset ) ;
}
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 */
2014-08-26 01:24:55 +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 ) ;
2014-08-26 03:51:49 +08:00
convert_to_long ( & tmp ) ;
2012-01-26 09:28:37 +08:00
offset = & tmp ;
}
2010-07-16 19:44:30 +08:00
}
2014-10-17 04:17:13 +08:00
if ( EXPECTED ( Z_TYPE_P ( offset ) = = IS_LONG ) ) {
2014-09-16 19:22:00 +08:00
if ( offset - > value . lval > = 0 & & ( size_t ) offset - > value . lval < Z_STRLEN_P ( container ) ) {
2014-04-07 18:56:34 +08:00
if ( ( opline - > extended_value & ZEND_ISSET ) | |
Z_STRVAL_P ( container ) [ offset - > value . lval ] ! = ' 0 ' ) {
2010-07-16 19:44:30 +08:00
result = 1 ;
2015-01-03 17:22:58 +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 ;
}
2014-12-08 23:11:14 +08:00
} else if ( ( OP1_TYPE & ( IS_VAR | IS_CV ) ) & & Z_ISREF_P ( container ) ) {
container = Z_REFVAL_P ( container ) ;
ZEND_VM_C_GOTO ( isset_dim_obj_again ) ;
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 ) ;
2014-06-01 02:05:03 +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 ( ) ;
}
2014-12-08 23:11:14 +08:00
ZEND_VM_HANDLER ( 148 , ZEND_ISSET_ISEMPTY_PROP_OBJ , CONST | TMPVAR | UNUSED | CV , CONST | TMPVAR | CV )
2004-10-23 05:42:14 +08:00
{
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 ( ) ;
2014-12-08 23:11:14 +08:00
container = GET_OP1_OBJ_ZVAL_PTR ( BP_VAR_IS ) ;
2014-04-22 04:32:29 +08:00
offset = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2014-12-08 23:11:14 +08:00
if ( OP1_TYPE ! = IS_UNUSED & & UNEXPECTED ( Z_TYPE_P ( container ) ! = IS_OBJECT ) ) {
if ( ( OP1_TYPE & ( IS_VAR | IS_CV ) ) & & Z_ISREF_P ( container ) ) {
container = Z_REFVAL_P ( container ) ;
if ( UNEXPECTED ( Z_TYPE_P ( container ) ! = IS_OBJECT ) ) {
ZEND_VM_C_GOTO ( isset_no_object ) ;
}
2014-04-22 04:32:29 +08:00
} else {
2014-12-08 23:11:14 +08:00
ZEND_VM_C_GOTO ( isset_no_object ) ;
2014-04-22 04:32:29 +08:00
}
2014-12-08 23:11:14 +08:00
}
if ( UNEXPECTED ( ! Z_OBJ_HT_P ( container ) - > has_property ) ) {
zend_error ( E_NOTICE , " Trying to check property of non-object " ) ;
ZEND_VM_C_LABEL ( isset_no_object ) :
result = ( ( opline - > extended_value & ZEND_ISSET ) = = 0 ) ;
} else {
2015-02-25 06:52:35 +08:00
result = Z_OBJ_HT_P ( container ) - > has_property ( container , offset , ( opline - > extended_value & ZEND_ISSET ) = = 0 , ( ( OP2_TYPE = = IS_CONST ) ? CACHE_ADDR ( Z_CACHE_SLOT_P ( offset ) ) : NULL ) ) ;
2014-04-22 04:32:29 +08:00
if ( ( opline - > extended_value & ZEND_ISSET ) = = 0 ) {
result = ! result ;
}
}
FREE_OP2 ( ) ;
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , result ) ;
2014-06-01 02:05:03 +08:00
FREE_OP1 ( ) ;
2014-04-22 04:32:29 +08:00
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
2004-10-23 05:42:14 +08:00
}
2014-12-08 23:11:14 +08:00
ZEND_VM_HANDLER ( 79 , ZEND_EXIT , CONST | TMPVAR | UNUSED | CV , ANY )
2004-10-23 05:42:14 +08:00
{
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 ;
2014-12-08 23:11:14 +08:00
zval * ptr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2004-10-23 05:42:14 +08:00
2014-12-08 23:11:14 +08:00
do {
if ( Z_TYPE_P ( ptr ) = = IS_LONG ) {
EG ( exit_status ) = Z_LVAL_P ( ptr ) ;
} else {
if ( ( OP1_TYPE & ( IS_VAR | IS_CV ) ) & & Z_ISREF_P ( ptr ) ) {
ptr = Z_REFVAL_P ( ptr ) ;
if ( Z_TYPE_P ( ptr ) = = IS_LONG ) {
EG ( exit_status ) = Z_LVAL_P ( ptr ) ;
break ;
2015-01-03 17:22:58 +08:00
}
2014-12-08 23:11:14 +08:00
}
2014-12-14 06:06:14 +08:00
zend_print_variable ( ptr ) ;
2014-12-08 23:11:14 +08:00
}
} while ( 0 ) ;
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-09-03 19:17:50 +08:00
ZVAL_LONG ( EX_VAR ( opline - > result . var ) , EG ( error_reporting ) ) ;
2006-05-12 05:07:39 +08:00
2014-09-03 19:17:50 +08:00
if ( EG ( error_reporting ) ) {
do {
2014-09-03 02:13:24 +08:00
EG ( error_reporting ) = 0 ;
2014-09-03 19:17:50 +08:00
if ( ! EG ( error_reporting_ini_entry ) ) {
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 {
break ;
}
}
2010-08-18 21:58:13 +08:00
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_modifiable = EG ( error_reporting_ini_entry ) - > modifiable ;
EG ( error_reporting_ini_entry ) - > modified = 1 ;
}
}
2014-09-03 19:17:50 +08:00
} while ( 0 ) ;
}
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
ZEND_VM_HANDLER ( 58 , ZEND_END_SILENCE , TMP , ANY )
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-09-03 19:17:50 +08:00
if ( ! EG ( error_reporting ) & & Z_LVAL_P ( EX_VAR ( opline - > op1 . var ) ) ! = 0 ) {
EG ( error_reporting ) = Z_LVAL_P ( EX_VAR ( opline - > op1 . var ) ) ;
}
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 ;
2014-09-11 23:12:12 +08:00
int is_ref = 0 ;
2010-04-20 19:16:39 +08:00
SAVE_OPLINE ( ) ;
2014-09-11 23:12:12 +08:00
value = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2011-10-19 03:42:42 +08:00
2014-09-11 23:12:12 +08:00
if ( ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) & & Z_ISREF_P ( value ) ) {
is_ref = 1 ;
value = Z_REFVAL_P ( value ) ;
}
2014-12-14 06:06:14 +08:00
if ( i_zend_is_true ( value ) ) {
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 ) ;
2014-09-11 23:12:12 +08:00
} else if ( OP1_TYPE = = IS_VAR & & is_ref ) {
if ( Z_OPT_REFCOUNTED_P ( value ) ) Z_ADDREF_P ( value ) ;
FREE_OP1 ( ) ;
2011-10-19 03:42:42 +08:00
}
2014-12-12 15:19:41 +08:00
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
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 ( ) ;
}
2014-09-17 02:14:46 +08:00
ZEND_VM_HANDLER ( 169 , ZEND_COALESCE , CONST | TMP | VAR | CV , ANY )
{
USE_OPLINE
zend_free_op free_op1 ;
zval * value ;
int is_ref = 0 ;
SAVE_OPLINE ( ) ;
value = GET_OP1_ZVAL_PTR ( BP_VAR_IS ) ;
if ( ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) & & Z_ISREF_P ( value ) ) {
is_ref = 1 ;
value = Z_REFVAL_P ( value ) ;
}
if ( Z_TYPE_P ( value ) > IS_NULL ) {
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 ) ) ;
}
} else if ( OP1_TYPE = = IS_CV ) {
if ( Z_OPT_REFCOUNTED_P ( value ) ) Z_ADDREF_P ( value ) ;
} else if ( OP1_TYPE = = IS_VAR & & is_ref ) {
if ( Z_OPT_REFCOUNTED_P ( value ) ) Z_ADDREF_P ( value ) ;
FREE_OP1 ( ) ;
}
2014-12-12 15:19:41 +08:00
ZEND_VM_JMP ( OP_JMP_ADDR ( opline , opline - > op2 ) ) ;
2014-09-17 02:14:46 +08:00
}
FREE_OP1 ( ) ;
CHECK_EXCEPTION ( ) ;
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 ( ) ;
2014-09-11 23:12:12 +08:00
value = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2011-10-19 03:42:42 +08:00
2014-09-11 23:12:12 +08:00
if ( ( OP1_TYPE = = IS_VAR | | OP1_TYPE = = IS_CV ) & & Z_ISREF_P ( value ) ) {
ZVAL_COPY ( EX_VAR ( opline - > result . var ) , Z_REFVAL_P ( value ) ) ;
FREE_OP1 ( ) ;
} else {
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 ) ) ;
}
} 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-12-14 06:06:14 +08:00
zend_llist_apply_with_argument ( & zend_extensions , ( llist_apply_with_arg_func_t ) zend_extension_statement_handler , EX ( func ) ) ;
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-12-14 06:06:14 +08:00
zend_llist_apply_with_argument ( & zend_extensions , ( llist_apply_with_arg_func_t ) zend_extension_fcall_begin_handler , EX ( func ) ) ;
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-12-14 06:06:14 +08:00
zend_llist_apply_with_argument ( & zend_extensions , ( llist_apply_with_arg_func_t ) zend_extension_fcall_end_handler , EX ( func ) ) ;
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-12-14 06:06:14 +08:00
Z_CE_P ( EX_VAR ( opline - > result . var ) ) = do_bind_class ( & EX ( func ) - > op_array , opline , EG ( class_table ) , 0 ) ;
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-12-14 06:06:14 +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 ) ;
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-12-12 15:19:41 +08:00
if ( ( zce = zend_hash_find ( EG ( class_table ) , Z_STR_P ( EX_CONSTANT ( opline - > op2 ) ) ) ) = = NULL | |
( ( orig_zce = zend_hash_find ( EG ( class_table ) , Z_STR_P ( EX_CONSTANT ( opline - > op1 ) ) ) ) ! = NULL & &
2014-02-10 14:04:30 +08:00
Z_CE_P ( zce ) ! = Z_CE_P ( orig_zce ) ) ) {
2014-12-14 06:06:14 +08:00
do_bind_inherited_class ( & EX ( func ) - > op_array , opline , EG ( class_table ) , Z_CE_P ( EX_VAR ( opline - > extended_value ) ) , 0 ) ;
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-12-14 06:06:14 +08:00
do_bind_function ( & EX ( func ) - > op_array , opline , EG ( function_table ) , 0 ) ;
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 ( ) ;
2014-12-13 02:57:34 +08:00
if ( ( uint32_t ) + + EG ( ticks_count ) > = opline - > extended_value ) {
EG ( ticks_count ) = 0 ;
2004-10-23 05:42:14 +08:00
if ( zend_ticks_function ) {
2014-12-14 06:06:14 +08:00
zend_ticks_function ( opline - > extended_value ) ;
2004-10-23 05:42:14 +08:00
}
}
2010-04-20 19:16:39 +08:00
CHECK_EXCEPTION ( ) ;
2004-10-23 05:42:14 +08:00
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-12-05 23:23:39 +08:00
ZEND_VM_HANDLER ( 138 , ZEND_INSTANCEOF , TMPVAR | CV , CONST | VAR )
2004-10-23 05:42:14 +08:00
{
2010-04-20 19:16:39 +08:00
USE_OPLINE
2004-10-23 05:42:14 +08:00
zend_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-12-05 23:23:39 +08:00
expr = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
2011-03-16 13:25:02 +08:00
2014-12-05 23:23:39 +08:00
ZEND_VM_C_LABEL ( try_instanceof ) :
2014-10-09 19:58:14 +08:00
if ( Z_TYPE_P ( expr ) = = IS_OBJECT ) {
2014-10-22 21:23:43 +08:00
zend_class_entry * ce ;
if ( OP2_TYPE = = IS_CONST ) {
2014-12-12 15:19:41 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ) {
ce = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
2014-10-22 21:23:43 +08:00
} else {
2014-12-14 06:06:14 +08:00
ce = zend_fetch_class_by_name ( Z_STR_P ( EX_CONSTANT ( opline - > op2 ) ) , EX_CONSTANT ( opline - > op2 ) + 1 , ZEND_FETCH_CLASS_NO_AUTOLOAD ) ;
2014-10-22 21:23:43 +08:00
if ( UNEXPECTED ( ce = = NULL ) ) {
ZVAL_FALSE ( EX_VAR ( opline - > result . var ) ) ;
FREE_OP1 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-12-12 15:19:41 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) , ce ) ;
2014-10-22 21:23:43 +08:00
}
} else {
ce = Z_CE_P ( EX_VAR ( opline - > op2 . var ) ) ;
}
2015-01-14 20:06:26 +08:00
result = ce & & instanceof_function ( Z_OBJCE_P ( expr ) , ce ) ;
2014-12-05 23:23:39 +08:00
} else if ( ( OP1_TYPE & ( IS_VAR | IS_CV ) ) & & Z_TYPE_P ( expr ) = = IS_REFERENCE ) {
expr = Z_REFVAL_P ( expr ) ;
ZEND_VM_C_GOTO ( try_instanceof ) ;
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-12-12 15:19:41 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ) {
iface = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-12-14 06:06:14 +08:00
iface = zend_fetch_class_by_name ( Z_STR_P ( EX_CONSTANT ( opline - > op2 ) ) , EX_CONSTANT ( opline - > op2 ) + 1 , ZEND_FETCH_CLASS_INTERFACE ) ;
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-12-12 15:19:41 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) , 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
}
2014-12-14 06:06:14 +08:00
zend_do_implement_interface ( ce , iface ) ;
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-12-12 15:19:41 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ) {
trait = CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) ) ;
2010-05-24 22:11:39 +08:00
} else {
2014-12-12 15:19:41 +08:00
trait = zend_fetch_class_by_name ( Z_STR_P ( EX_CONSTANT ( opline - > op2 ) ) ,
EX_CONSTANT ( opline - > op2 ) + 1 ,
2014-12-14 06:06:14 +08:00
ZEND_FETCH_CLASS_TRAIT ) ;
2010-05-24 22:11:39 +08:00
if ( UNEXPECTED ( trait = = NULL ) ) {
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2015-02-13 06:19:14 +08:00
if ( ! ( trait - > ce_flags & 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-12-12 15:19:41 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op2 ) ) , 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
}
2014-12-14 06:06:14 +08:00
zend_do_implement_trait ( ce , trait ) ;
2010-05-24 22:11:39 +08:00
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 ( ) ;
2014-12-14 06:06:14 +08:00
zend_do_bind_traits ( ce ) ;
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-08-26 01:28:33 +08:00
uint32_t op_num = EG ( opline_before_exception ) - EX ( func ) - > op_array . opcodes ;
2004-10-23 05:42:14 +08:00
int i ;
2014-08-26 01:28:33 +08:00
uint32_t catch_op_num = 0 , finally_op_num = 0 , finally_op_end = 0 ;
2014-12-02 21:05:30 +08:00
int in_finally = 0 ;
2008-01-24 17:41:39 +08:00
2015-03-17 00:48:29 +08:00
ZEND_VM_INTERRUPT_CHECK ( ) ;
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-12-02 21:05:30 +08:00
in_finally = 0 ;
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 ;
2014-11-27 14:56:43 +08:00
finally_op_end = EX ( func ) - > op_array . try_catch_array [ i ] . finally_end ;
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 ;
2014-12-02 21:05:30 +08:00
in_finally = 1 ;
2013-12-13 00:15:50 +08:00
}
2004-10-23 05:42:14 +08:00
}
2014-12-16 23:40:52 +08:00
if ( UNEXPECTED ( EX ( call ) ) ) {
2014-06-30 19:43:45 +08:00
zend_execute_data * call = EX ( call ) ;
2014-12-16 23:40:52 +08:00
zend_op * opline = EX ( func ) - > op_array . opcodes + op_num ;
int level ;
int do_exit ;
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 . */
2014-12-16 23:40:52 +08:00
/* find the number of actually passed arguments */
level = 0 ;
do_exit = 0 ;
do {
switch ( opline - > opcode ) {
case ZEND_DO_FCALL :
2015-02-25 15:37:21 +08:00
case ZEND_DO_ICALL :
case ZEND_DO_UCALL :
case ZEND_DO_FCALL_BY_NAME :
2014-12-16 23:40:52 +08:00
level + + ;
2015-01-03 17:22:58 +08:00
break ;
2014-12-16 23:40:52 +08:00
case ZEND_INIT_FCALL :
case ZEND_INIT_FCALL_BY_NAME :
case ZEND_INIT_NS_FCALL_BY_NAME :
2015-02-25 03:29:47 +08:00
case ZEND_INIT_DYNAMIC_CALL :
2014-12-16 23:40:52 +08:00
case ZEND_INIT_USER_CALL :
case ZEND_INIT_METHOD_CALL :
case ZEND_INIT_STATIC_METHOD_CALL :
case ZEND_NEW :
if ( level = = 0 ) {
ZEND_CALL_NUM_ARGS ( call ) = 0 ;
2015-01-03 17:22:58 +08:00
do_exit = 1 ;
2014-12-16 23:40:52 +08:00
}
level - - ;
break ;
case ZEND_SEND_VAL :
case ZEND_SEND_VAL_EX :
case ZEND_SEND_VAR :
case ZEND_SEND_VAR_EX :
case ZEND_SEND_REF :
case ZEND_SEND_VAR_NO_REF :
case ZEND_SEND_USER :
if ( level = = 0 ) {
ZEND_CALL_NUM_ARGS ( call ) = opline - > op2 . num ;
2015-01-03 17:22:58 +08:00
do_exit = 1 ;
2014-12-16 23:40:52 +08:00
}
break ;
case ZEND_SEND_ARRAY :
case ZEND_SEND_UNPACK :
if ( level = = 0 ) {
do_exit = 1 ;
}
break ;
}
if ( ! do_exit ) {
opline - - ;
}
} while ( ! do_exit ) ;
if ( call - > prev_execute_data ) {
/* skip current call region */
level = 0 ;
do_exit = 0 ;
do {
switch ( opline - > opcode ) {
case ZEND_DO_FCALL :
2015-02-25 15:37:21 +08:00
case ZEND_DO_ICALL :
case ZEND_DO_UCALL :
case ZEND_DO_FCALL_BY_NAME :
2014-12-16 23:40:52 +08:00
level + + ;
2015-01-03 17:22:58 +08:00
break ;
2014-12-16 23:40:52 +08:00
case ZEND_INIT_FCALL :
case ZEND_INIT_FCALL_BY_NAME :
case ZEND_INIT_NS_FCALL_BY_NAME :
2015-02-25 03:29:47 +08:00
case ZEND_INIT_DYNAMIC_CALL :
2014-12-16 23:40:52 +08:00
case ZEND_INIT_USER_CALL :
case ZEND_INIT_METHOD_CALL :
case ZEND_INIT_STATIC_METHOD_CALL :
case ZEND_NEW :
if ( level = = 0 ) {
2015-01-03 17:22:58 +08:00
do_exit = 1 ;
2014-12-16 23:40:52 +08:00
}
level - - ;
break ;
}
opline - - ;
} while ( ! do_exit ) ;
}
2014-12-14 06:06:14 +08:00
zend_vm_stack_free_args ( EX ( call ) ) ;
2014-06-30 19:43:45 +08:00
2014-10-03 23:32:46 +08:00
if ( Z_OBJ ( call - > This ) ) {
2014-11-28 15:33:03 +08:00
if ( ZEND_CALL_INFO ( call ) & ZEND_CALL_CTOR ) {
if ( ! ( ZEND_CALL_INFO ( call ) & ZEND_CALL_CTOR_RESULT_UNUSED ) ) {
2014-10-03 23:32:46 +08:00
GC_REFCOUNT ( Z_OBJ ( call - > This ) ) - - ;
2012-11-30 17:39:23 +08:00
}
2014-10-03 23:32:46 +08:00
if ( GC_REFCOUNT ( Z_OBJ ( call - > This ) ) = = 1 ) {
2014-12-14 06:06:14 +08:00
zend_object_store_ctor_failed ( Z_OBJ ( call - > This ) ) ;
2012-11-30 17:39:23 +08:00
}
2009-03-26 18:17:30 +08:00
}
2014-10-03 23:32:46 +08:00
OBJ_RELEASE ( Z_OBJ ( call - > This ) ) ;
2005-10-20 15:23:26 +08:00
}
2015-03-11 01:26:09 +08:00
if ( call - > func - > common . fn_flags & ZEND_ACC_CALL_VIA_HANDLER ) {
zend_string_release ( call - > func - > common . function_name ) ;
efree ( call - > func ) ;
2015-03-11 01:17:56 +08:00
}
2015-03-11 01:26:09 +08:00
2014-10-01 14:46:13 +08:00
EX ( call ) = call - > prev_execute_data ;
2014-12-14 06:06:14 +08:00
zend_vm_stack_free_call_frame ( call ) ;
2014-06-30 19:43:45 +08:00
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-09-23 21:21:29 +08:00
if ( brk_opline - > opcode = = ZEND_FREE ) {
2014-06-05 22:42:17 +08:00
if ( ! ( brk_opline - > extended_value & EXT_TYPE_FREE_ON_RETURN ) ) {
2014-09-23 21:21:29 +08:00
zval_ptr_dtor_nogc ( EX_VAR ( brk_opline - > op1 . var ) ) ;
2014-06-05 22:42:17 +08:00
}
2015-02-12 18:57:12 +08:00
} else if ( brk_opline - > opcode = = ZEND_FE_FREE ) {
if ( ! ( brk_opline - > extended_value & EXT_TYPE_FREE_ON_RETURN ) ) {
zval * var = EX_VAR ( brk_opline - > op1 . var ) ;
if ( Z_TYPE_P ( var ) ! = IS_ARRAY & & Z_FE_ITER_P ( var ) ! = ( uint32_t ) - 1 ) {
zend_hash_iterator_del ( Z_FE_ITER_P ( var ) ) ;
}
zval_ptr_dtor_nogc ( var ) ;
}
2014-11-27 03:44:58 +08:00
} else if ( brk_opline - > opcode = = ZEND_END_SILENCE ) {
/* restore previous error_reporting value */
if ( ! EG ( error_reporting ) & & Z_LVAL_P ( EX_VAR ( brk_opline - > op1 . var ) ) ! = 0 ) {
EG ( error_reporting ) = Z_LVAL_P ( EX_VAR ( brk_opline - > op1 . var ) ) ;
}
2006-09-20 05:36:54 +08:00
}
}
}
}
2012-11-22 19:17:05 +08:00
if ( finally_op_num & & ( ! catch_op_num | | catch_op_num > = finally_op_num ) ) {
2014-11-27 14:56:43 +08:00
zval * fast_call = EX_VAR ( EX ( func ) - > op_array . opcodes [ finally_op_end ] . op1 . var ) ;
2014-12-02 21:05:30 +08:00
if ( in_finally & & Z_OBJ_P ( fast_call ) ) {
2014-12-14 06:06:14 +08:00
zend_exception_set_previous ( EG ( exception ) , Z_OBJ_P ( fast_call ) ) ;
2015-01-03 17:22:58 +08:00
}
2014-11-27 14:56:43 +08:00
Z_OBJ_P ( fast_call ) = EG ( exception ) ;
2013-12-13 00:15:50 +08:00
EG ( exception ) = NULL ;
2014-11-27 14:56:43 +08:00
fast_call - > u2 . lineno = ( uint32_t ) - 1 ;
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 ( ) ;
} else {
2014-12-02 21:05:30 +08:00
if ( in_finally ) {
/* we are going out of current finally scope */
2014-11-27 14:56:43 +08:00
zval * fast_call = EX_VAR ( EX ( func ) - > op_array . opcodes [ finally_op_end ] . op1 . var ) ;
if ( Z_OBJ_P ( fast_call ) ) {
2014-12-14 06:06:14 +08:00
zend_exception_set_previous ( EG ( exception ) , Z_OBJ_P ( fast_call ) ) ;
2014-11-27 14:56:43 +08:00
Z_OBJ_P ( fast_call ) = NULL ;
}
2013-12-13 00:15:50 +08:00
}
2014-12-02 21:05:30 +08:00
if ( catch_op_num ) {
ZEND_VM_SET_OPCODE ( & EX ( func ) - > op_array . opcodes [ catch_op_num ] ) ;
ZEND_VM_CONTINUE ( ) ;
} else if ( UNEXPECTED ( ( EX ( func ) - > op_array . fn_flags & ZEND_ACC_GENERATOR ) ! = 0 ) ) {
2015-02-20 03:17:37 +08:00
/* The generator object is stored in EX(return_value) */
zend_generator * generator = ( zend_generator * ) EX ( return_value ) ;
zend_generator_close ( generator , 1 ) ;
ZEND_VM_RETURN ( ) ;
2012-12-11 21:25:32 +08:00
} 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-12-14 06:06:14 +08:00
zend_verify_abstract_class ( Z_CE_P ( 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 ( ) ;
}
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 ( ) ;
2015-03-13 01:39:04 +08:00
ret = zend_user_opcode_handlers [ opline - > opcode ] ( execute_data ) ;
2010-04-20 19:16:39 +08:00
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 ) ) {
2015-02-20 03:17:37 +08:00
/* The generator object is stored in EX(return_value) */
zend_generator * generator = ( zend_generator * ) EX ( return_value ) ;
zend_generator_close ( generator , 1 ) ;
ZEND_VM_RETURN ( ) ;
2012-12-11 21:25:32 +08:00
} 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-12-14 06:06:14 +08:00
zval_update_constant ( & c . value , 0 ) ;
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-08-26 01:24:55 +08:00
c . name = zend_string_dup ( Z_STR_P ( name ) , 0 ) ;
2007-09-29 03:52:53 +08:00
c . module_number = PHP_USER_CONSTANT ;
2014-12-14 06:06:14 +08:00
if ( zend_register_constant ( & c ) = = FAILURE ) {
2007-09-29 03:52:53 +08:00
}
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 ( ) ;
2015-03-09 20:57:15 +08:00
zfunc = zend_hash_find ( EG ( function_table ) , Z_STR_P ( EX_CONSTANT ( opline - > op1 ) ) ) ;
ZEND_ASSERT ( zfunc ! = NULL & & Z_FUNC_P ( zfunc ) - > type = = ZEND_USER_FUNCTION ) ;
2008-07-14 17:49:03 +08:00
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-12-14 06:06:14 +08:00
zend_create_closure ( EX_VAR ( opline - > result . var ) , Z_FUNC_P ( zfunc ) , EX ( called_scope ) , NULL ) ;
2014-05-13 11:53:08 +08:00
} else {
2014-12-14 06:06:14 +08:00
zend_create_closure ( EX_VAR ( opline - > result . var ) , Z_FUNC_P ( zfunc ) , EG ( scope ) , Z_OBJ ( EX ( This ) ) ? & EX ( This ) : NULL ) ;
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
2015-03-13 01:39:04 +08:00
SAVE_OPLINE ( ) ;
2012-08-25 23:40:08 +08:00
if ( generator - > flags & ZEND_GENERATOR_FORCED_CLOSE ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot yield from finally in a force-closed generator " ) ;
FREE_UNFETCHED_OP2 ( ) ;
FREE_UNFETCHED_OP1 ( ) ;
HANDLE_EXCEPTION ( ) ;
2012-08-25 23:40:08 +08:00
}
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 */
2014-09-22 16:47:10 +08:00
if ( OP1_TYPE ! = IS_TMP_VAR ) {
2014-09-24 16:20:46 +08:00
zval_opt_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-09-08 19:46:45 +08:00
if ( OP1_TYPE = = IS_VAR & & UNEXPECTED ( value_ptr = = NULL ) ) {
2015-03-09 20:57:15 +08:00
zend_error ( E_EXCEPTION | E_ERROR , " Cannot yield string offsets by reference " ) ;
FREE_UNFETCHED_OP2 ( ) ;
FREE_OP1 ( ) ;
HANDLE_EXCEPTION ( ) ;
2012-07-17 19:24:27 +08:00
}
/* If a function call result is yielded and the function did
* not return by reference we throw a notice . */
2014-10-23 01:45:02 +08:00
if ( OP1_TYPE = = IS_VAR & &
( value_ptr = = & EG ( uninitialized_zval ) | |
( opline - > extended_value = = ZEND_RETURNS_FUNCTION & &
! ( 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-09-22 20:17:35 +08:00
} else if ( ( OP1_TYPE = = IS_CV | | OP1_TYPE = = IS_VAR ) & & Z_ISREF_P ( value ) ) {
2014-04-16 05:45:40 +08:00
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 {
2014-09-22 20:17:35 +08:00
ZVAL_COPY_VALUE ( & generator - > value , value ) ;
2013-05-17 17:15:09 +08:00
if ( OP1_TYPE = = IS_CV ) {
2014-09-22 20:17:35 +08:00
if ( Z_OPT_REFCOUNTED_P ( value ) ) Z_ADDREF_P ( value ) ;
2013-05-17 17:15:09 +08:00
}
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-09-22 20:17:35 +08:00
} else if ( ( OP2_TYPE = = IS_VAR | | OP2_TYPE = = IS_CV ) & & Z_ISREF_P ( key ) ) {
2014-04-16 05:45:40 +08:00
ZVAL_DUP ( & generator - > key , Z_REFVAL_P ( key ) ) ;
FREE_OP2_IF_VAR ( ) ;
2012-05-30 08:44:06 +08:00
} else {
2014-09-22 20:17:35 +08:00
ZVAL_COPY_VALUE ( & generator - > key , key ) ;
2014-04-16 20:35:41 +08:00
if ( OP2_TYPE = = IS_CV ) {
2014-09-22 20:17:35 +08:00
if ( Z_OPT_REFCOUNTED_P ( key ) ) Z_ADDREF_P ( key ) ;
2014-04-16 05:45:40 +08:00
}
2012-05-30 08:44:06 +08:00
}
2014-08-26 01:24:55 +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-08-26 01:24:55 +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-08-26 01:24:55 +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 )
{
2014-11-27 14:56:43 +08:00
USE_OPLINE
zval * fast_call = EX_VAR ( opline - > op1 . var ) ;
2015-01-03 17:22:58 +08:00
2014-11-27 14:56:43 +08:00
/* check for delayed exception */
if ( Z_OBJ_P ( fast_call ) ! = NULL ) {
2015-03-13 01:39:04 +08:00
SAVE_OPLINE ( ) ;
2012-12-13 06:48:51 +08:00
/* discard the previously thrown exception */
2014-11-27 14:56:43 +08:00
OBJ_RELEASE ( Z_OBJ_P ( fast_call ) ) ;
Z_OBJ_P ( fast_call ) = 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
2014-11-27 14:56:43 +08:00
zval * fast_call = EX_VAR ( opline - > result . var ) ;
2012-11-22 19:17:05 +08:00
2014-07-19 17:19:01 +08:00
if ( ( opline - > extended_value & ZEND_FAST_CALL_FROM_CATCH ) & &
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 ( ) ;
}
2014-11-27 14:56:43 +08:00
/* set no delayed exception */
Z_OBJ_P ( fast_call ) = NULL ;
/* set return address */
fast_call - > u2 . lineno = opline - EX ( func ) - > op_array . opcodes ;
2014-12-12 15:19:41 +08:00
ZEND_VM_SET_OPCODE ( OP_JMP_ADDR ( opline , opline - > op1 ) ) ;
2012-11-22 19:17:05 +08:00
ZEND_VM_CONTINUE ( ) ;
}
ZEND_VM_HANDLER ( 163 , ZEND_FAST_RET , ANY , ANY )
{
2014-11-27 14:56:43 +08:00
USE_OPLINE
zval * fast_call = EX_VAR ( opline - > op1 . var ) ;
if ( fast_call - > u2 . lineno ! = ( uint32_t ) - 1 ) {
const zend_op * fast_ret = EX ( func ) - > op_array . opcodes + fast_call - > u2 . lineno ;
ZEND_VM_SET_OPCODE ( fast_ret + 1 ) ;
if ( fast_ret - > extended_value & ZEND_FAST_CALL_FROM_FINALLY ) {
fast_call - > u2 . lineno = fast_ret - > op2 . opline_num ;
2014-07-18 15:45:31 +08:00
}
2012-11-22 19:17:05 +08:00
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 {
2014-11-27 14:56:43 +08:00
EG ( exception ) = Z_OBJ_P ( fast_call ) ;
Z_OBJ_P ( fast_call ) = NULL ;
2013-12-13 00:15:50 +08:00
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 ) ) {
2015-02-20 03:17:37 +08:00
/* The generator object is stored in EX(return_value) */
zend_generator * generator = ( zend_generator * ) EX ( return_value ) ;
zend_generator_close ( generator , 1 ) ;
ZEND_VM_RETURN ( ) ;
2013-12-13 00:15:50 +08:00
} else {
ZEND_VM_DISPATCH_TO_HELPER ( zend_leave_helper ) ;
}
2012-11-22 19:17:05 +08:00
}
}
}
2014-12-06 07:14:45 +08:00
ZEND_VM_HANDLER ( 166 , ZEND_POW , CONST | TMPVAR | CV , CONST | TMPVAR | CV )
2013-11-19 15:36:06 +08:00
{
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 ) ,
2014-12-06 07:14:45 +08:00
GET_OP1_ZVAL_PTR ( BP_VAR_R ) ,
2014-12-14 06:06:14 +08:00
GET_OP2_ZVAL_PTR ( BP_VAR_R ) ) ;
2013-11-19 15:36:06 +08:00
FREE_OP1 ( ) ;
FREE_OP2 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-12-06 08:03:48 +08:00
ZEND_VM_HANDLER ( 167 , ZEND_ASSIGN_POW , VAR | CV , CONST | TMPVAR | CV )
2013-11-19 15:36:06 +08:00
{
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 ;
2014-09-17 04:52:45 +08:00
uint32_t idx ;
2014-06-06 19:04:30 +08:00
SAVE_OPLINE ( ) ;
varname = GET_OP2_ZVAL_PTR ( BP_VAR_R ) ;
2015-01-03 17:22:58 +08:00
2014-11-24 20:46:34 +08:00
/* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
idx = ( uint32_t ) ( uintptr_t ) CACHED_PTR ( Z_CACHE_SLOT_P ( varname ) ) - 1 ;
2015-02-14 03:20:39 +08:00
if ( EXPECTED ( idx < EG ( symbol_table ) . nNumUsed ) ) {
Bucket * p = EG ( symbol_table ) . arData + idx ;
2014-11-24 20:46:34 +08:00
if ( EXPECTED ( Z_TYPE ( p - > val ) ! = IS_UNDEF ) & &
( EXPECTED ( p - > key = = Z_STR_P ( varname ) ) | |
( EXPECTED ( p - > h = = Z_STR_P ( varname ) - > h ) & &
EXPECTED ( p - > key ! = NULL ) & &
EXPECTED ( p - > key - > len = = Z_STRLEN_P ( varname ) ) & &
EXPECTED ( memcmp ( p - > key - > val , Z_STRVAL_P ( varname ) , Z_STRLEN_P ( varname ) ) = = 0 ) ) ) ) {
2015-01-03 17:22:58 +08:00
2015-02-14 03:20:39 +08:00
value = & EG ( symbol_table ) . arData [ idx ] . val ;
2014-11-24 20:46:34 +08:00
ZEND_VM_C_GOTO ( check_indirect ) ;
}
}
2015-02-14 03:20:39 +08:00
value = zend_hash_find ( & EG ( symbol_table ) , Z_STR_P ( varname ) ) ;
2014-11-24 20:46:34 +08:00
if ( UNEXPECTED ( value = = NULL ) ) {
2015-02-14 03:20:39 +08:00
value = zend_hash_add_new ( & EG ( symbol_table ) , Z_STR_P ( varname ) , & EG ( uninitialized_zval ) ) ;
idx = ( ( char * ) value - ( char * ) EG ( symbol_table ) . arData ) / sizeof ( Bucket ) ;
2014-11-24 20:46:34 +08:00
/* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
CACHE_PTR ( Z_CACHE_SLOT_P ( varname ) , ( void * ) ( uintptr_t ) ( idx + 1 ) ) ;
} else {
2015-02-14 03:20:39 +08:00
idx = ( ( char * ) value - ( char * ) EG ( symbol_table ) . arData ) / sizeof ( Bucket ) ;
2014-11-24 20:46:34 +08:00
/* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
CACHE_PTR ( Z_CACHE_SLOT_P ( varname ) , ( void * ) ( uintptr_t ) ( idx + 1 ) ) ;
ZEND_VM_C_LABEL ( check_indirect ) :
2014-06-06 19:04:30 +08:00
/* GLOBAL variable may be an INDIRECT pointer to CV */
2014-09-17 04:52:45 +08:00
if ( UNEXPECTED ( Z_TYPE_P ( value ) = = IS_INDIRECT ) ) {
value = Z_INDIRECT_P ( value ) ;
if ( UNEXPECTED ( Z_TYPE_P ( value ) = = IS_UNDEF ) ) {
ZVAL_NULL ( value ) ;
}
}
2014-06-06 19:04:30 +08:00
}
variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF ( BP_VAR_W ) ;
2014-12-14 06:06:14 +08:00
zend_assign_to_variable_reference ( variable_ptr , value ) ;
2014-06-06 19:04:30 +08:00
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-12-05 23:23:39 +08:00
ZEND_VM_HANDLER ( 121 , ZEND_STRLEN , CONST | TMPVAR | CV , ANY )
2014-07-11 22:52:27 +08:00
{
USE_OPLINE
zval * value ;
zend_free_op free_op1 ;
SAVE_OPLINE ( ) ;
2014-12-05 23:23:39 +08:00
value = GET_OP1_ZVAL_PTR ( BP_VAR_R ) ;
ZEND_VM_C_LABEL ( try_strlen ) :
2014-07-11 22:52:27 +08:00
if ( EXPECTED ( Z_TYPE_P ( value ) = = IS_STRING ) ) {
2014-08-26 01:24:55 +08:00
ZVAL_LONG ( EX_VAR ( opline - > result . var ) , Z_STRLEN_P ( value ) ) ;
2015-03-20 21:04:04 +08:00
} else {
zend_bool strict ;
2014-12-05 23:23:39 +08:00
if ( ( OP1_TYPE & ( IS_VAR | IS_CV ) ) & & Z_TYPE_P ( value ) = = IS_REFERENCE ) {
value = Z_REFVAL_P ( value ) ;
ZEND_VM_C_GOTO ( try_strlen ) ;
2014-07-11 22:52:27 +08:00
}
2015-03-20 21:04:04 +08:00
strict = EX_USES_STRICT_TYPES ( ) ;
do {
if ( EXPECTED ( ! strict ) ) {
2015-03-21 04:18:52 +08:00
zend_string * str ;
zval tmp ;
ZVAL_COPY ( & tmp , value ) ;
if ( zend_parse_arg_str_weak ( & tmp , & str ) ) {
2015-03-20 21:04:04 +08:00
ZVAL_LONG ( EX_VAR ( opline - > result . var ) , str - > len ) ;
2015-03-21 04:18:52 +08:00
zval_ptr_dtor ( & tmp ) ;
2015-03-20 21:04:04 +08:00
break ;
}
2015-03-21 04:18:52 +08:00
zval_ptr_dtor ( & tmp ) ;
2015-03-20 21:04:04 +08:00
}
zend_internal_type_error ( strict , " strlen() expects parameter 1 to be string, %s given " , zend_get_type_by_const ( Z_TYPE_P ( value ) ) ) ;
ZVAL_NULL ( EX_VAR ( opline - > result . var ) ) ;
} while ( 0 ) ;
2014-07-11 22:52:27 +08:00
}
FREE_OP1 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-07-14 14:33:11 +08:00
ZEND_VM_HANDLER ( 123 , ZEND_TYPE_CHECK , CONST | TMP | VAR | CV , ANY )
{
USE_OPLINE
zval * value ;
zend_free_op free_op1 ;
SAVE_OPLINE ( ) ;
value = GET_OP1_ZVAL_PTR_DEREF ( BP_VAR_R ) ;
switch ( opline - > extended_value ) {
case IS_NULL :
2014-08-26 01:24:55 +08:00
case IS_LONG :
2014-07-14 14:33:11 +08:00
case IS_DOUBLE :
case IS_STRING :
case IS_ARRAY :
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , Z_TYPE_P ( value ) = = opline - > extended_value ) ;
break ;
case _IS_BOOL :
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , Z_TYPE_P ( value ) = = IS_TRUE | | Z_TYPE_P ( value ) = = IS_FALSE ) ;
break ;
case IS_OBJECT :
if ( Z_TYPE_P ( value ) = = opline - > extended_value ) {
2014-10-09 19:58:14 +08:00
zend_class_entry * ce = Z_OBJCE_P ( value ) ;
2015-01-03 17:22:58 +08:00
if ( ce - > name - > len = = sizeof ( " __PHP_Incomplete_Class " ) - 1
2015-03-16 20:53:54 +08:00
& & ! memcmp ( ce - > name - > val , " __PHP_Incomplete_Class " , sizeof ( " __PHP_Incomplete_Class " ) - 1 ) ) {
2014-10-09 19:58:14 +08:00
ZVAL_FALSE ( EX_VAR ( opline - > result . var ) ) ;
2014-07-14 14:33:11 +08:00
} else {
2014-10-09 19:58:14 +08:00
ZVAL_TRUE ( EX_VAR ( opline - > result . var ) ) ;
2014-07-14 14:33:11 +08:00
}
} else {
ZVAL_FALSE ( EX_VAR ( opline - > result . var ) ) ;
}
break ;
case IS_RESOURCE :
if ( Z_TYPE_P ( value ) = = opline - > extended_value ) {
2014-12-14 06:06:14 +08:00
const char * type_name = zend_rsrc_list_get_rsrc_type ( Z_RES_P ( value ) ) ;
2014-07-14 14:33:11 +08:00
ZVAL_BOOL ( EX_VAR ( opline - > result . var ) , type_name ! = NULL ) ;
} else {
ZVAL_FALSE ( EX_VAR ( opline - > result . var ) ) ;
}
2014-07-23 05:11:12 +08:00
break ;
2014-07-14 14:33:11 +08:00
EMPTY_SWITCH_DEFAULT_CASE ( )
}
FREE_OP1 ( ) ;
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2014-07-14 19:43:11 +08:00
ZEND_VM_HANDLER ( 122 , ZEND_DEFINED , CONST , ANY )
{
USE_OPLINE
zend_constant * c ;
SAVE_OPLINE ( ) ;
2014-12-12 15:19:41 +08:00
if ( CACHED_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) ) ) {
2014-07-14 19:43:11 +08:00
ZVAL_TRUE ( EX_VAR ( opline - > result . var ) ) ;
2014-12-14 06:06:14 +08:00
} else if ( ( c = zend_quick_get_constant ( EX_CONSTANT ( opline - > op1 ) , 0 ) ) = = NULL ) {
2014-07-14 19:43:11 +08:00
ZVAL_FALSE ( EX_VAR ( opline - > result . var ) ) ;
} else {
2014-12-12 15:19:41 +08:00
CACHE_PTR ( Z_CACHE_SLOT_P ( EX_CONSTANT ( opline - > op1 ) ) , c ) ;
2014-07-14 19:43:11 +08:00
ZVAL_TRUE ( EX_VAR ( opline - > result . var ) ) ;
}
CHECK_EXCEPTION ( ) ;
ZEND_VM_NEXT_OPCODE ( ) ;
}
2015-03-02 17:25:40 +08:00
ZEND_VM_HANDLER ( 151 , ZEND_ASSERT_CHECK , ANY , ANY )
{
USE_OPLINE
if ( EG ( assertions ) < = 0 ) {
zend_op * target = OP_JMP_ADDR ( opline , opline - > op2 ) ;
if ( RETURN_VALUE_USED ( target - 1 ) ) {
ZVAL_TRUE ( EX_VAR ( ( target - 1 ) - > result . var ) ) ;
}
ZEND_VM_JMP ( target ) ;
} else {
ZEND_VM_NEXT_OPCODE ( ) ;
}
}
2015-03-18 22:09:57 +08:00
ZEND_VM_HANDLER ( 157 , ZEND_FETCH_CLASS_NAME , ANY , ANY )
2015-03-18 20:31:29 +08:00
{
USE_OPLINE
if ( EG ( scope ) & & EG ( scope ) - > name ) {
ZVAL_STR_COPY ( EX_VAR ( opline - > result . var ) , EG ( scope ) - > name ) ;
} else {
ZVAL_EMPTY_STRING ( EX_VAR ( opline - > result . var ) ) ;
}
ZEND_VM_NEXT_OPCODE ( ) ;
2015-03-20 16:10:29 +08:00
}