1999-04-08 02:10:10 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Zend Engine |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2002-12-31 23:59:15 +08:00
| Copyright ( c ) 1998 - 2003 Zend Technologies Ltd . ( http : //www.zend.com) |
1999-04-08 02:10:10 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2001-12-11 23:16:21 +08:00
| This source file is subject to version 2.00 of the Zend license , |
2002-10-25 02:04:12 +08:00
| that is bundled with this package in the file LICENSE , and is |
1999-07-16 22:58:16 +08:00
| available at through the world - wide - web at |
2001-12-11 23:16:21 +08:00
| http : //www.zend.com/license/2_00.txt. |
1999-07-16 22:58:16 +08:00
| 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 . |
1999-04-08 02:10:10 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Authors : Andi Gutmans < andi @ zend . com > |
| Zeev Suraski < zeev @ zend . com > |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2003-02-01 09:49:15 +08:00
/* $Id$ */
2000-02-10 05:48:16 +08:00
# define ZEND_INTENSIVE_DEBUGGING 0
1999-07-16 22:58:16 +08:00
1999-04-08 02:10:10 +08:00
# include <stdio.h>
# include <signal.h>
# include "zend.h"
# include "zend_compile.h"
# include "zend_execute.h"
# include "zend_API.h"
# include "zend_ptr_stack.h"
# include "zend_constants.h"
# include "zend_extensions.h"
1999-12-28 03:07:33 +08:00
# include "zend_fast_cache.h"
2000-02-02 06:04:52 +08:00
# include "zend_execute_locks.h"
2002-11-20 01:51:30 +08:00
# include "zend_ini.h"
1999-04-08 02:10:10 +08:00
2001-07-27 18:10:39 +08:00
# define get_zval_ptr(node, Ts, should_free, type) _get_zval_ptr(node, Ts, should_free TSRMLS_CC)
# define get_zval_ptr_ptr(node, Ts, type) _get_zval_ptr_ptr(node, Ts TSRMLS_CC)
1999-04-08 02:10:10 +08:00
/* Prototypes */
2001-11-25 02:27:20 +08:00
static void zend_fetch_var_address ( zend_op * opline , temp_variable * Ts , int type TSRMLS_DC ) ;
2001-07-27 18:10:39 +08:00
static void zend_fetch_dimension_address ( znode * result , znode * op1 , znode * op2 , temp_variable * Ts , int type TSRMLS_DC ) ;
static void zend_fetch_property_address ( znode * result , znode * op1 , znode * op2 , temp_variable * Ts , int type TSRMLS_DC ) ;
static void zend_fetch_dimension_address_from_tmp_var ( znode * result , znode * op1 , znode * op2 , temp_variable * Ts TSRMLS_DC ) ;
2001-07-31 12:53:54 +08:00
static void zend_extension_statement_handler ( zend_extension * extension , zend_op_array * op_array TSRMLS_DC ) ;
static void zend_extension_fcall_begin_handler ( zend_extension * extension , zend_op_array * op_array TSRMLS_DC ) ;
static void zend_extension_fcall_end_handler ( zend_extension * extension , zend_op_array * op_array TSRMLS_DC ) ;
1999-04-08 02:10:10 +08:00
1999-12-21 23:55:46 +08:00
# define RETURN_VALUE_USED(opline) (!((opline)->result.u.EA.type & EXT_TYPE_UNUSED))
2002-10-24 04:40:07 +08:00
# define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))
# define T(offset) (*(temp_variable *)((char *) Ts + offset))
2002-10-24 04:26:28 +08:00
2002-10-23 03:31:53 +08:00
static inline zval * _get_zval_ptr ( znode * node , temp_variable * Ts , zval * * should_free TSRMLS_DC )
1999-04-08 02:10:10 +08:00
{
2002-11-30 19:20:25 +08:00
switch ( node - > op_type ) {
1999-04-08 02:10:10 +08:00
case IS_CONST :
* should_free = 0 ;
return & node - > u . constant ;
break ;
case IS_TMP_VAR :
2002-10-24 04:26:28 +08:00
return * should_free = & T ( node - > u . var ) . tmp_var ;
1999-04-08 02:10:10 +08:00
break ;
case IS_VAR :
2002-10-24 04:26:28 +08:00
if ( T ( node - > u . var ) . var . ptr ) {
PZVAL_UNLOCK ( T ( node - > u . var ) . var . ptr ) ;
1999-04-08 02:10:10 +08:00
* should_free = 0 ;
2002-10-24 04:26:28 +08:00
return T ( node - > u . var ) . var . ptr ;
1999-04-08 02:10:10 +08:00
} else {
2002-10-24 04:26:28 +08:00
* should_free = & T ( node - > u . var ) . tmp_var ;
1999-04-08 02:10:10 +08:00
2002-10-24 04:26:28 +08:00
switch ( T ( node - > u . var ) . EA . type ) {
1999-04-08 02:10:10 +08:00
case IS_STRING_OFFSET : {
2002-10-24 04:26:28 +08:00
temp_variable * T = & T ( node - > u . var ) ;
2000-04-07 00:34:55 +08:00
zval * str = T - > EA . data . str_offset . str ;
1999-04-08 02:10:10 +08:00
2000-04-07 00:34:55 +08:00
if ( T - > EA . data . str_offset . str - > type ! = IS_STRING
2001-02-06 06:27:47 +08:00
| | ( T - > EA . data . str_offset . offset < 0 )
2000-04-07 00:34:55 +08:00
| | ( T - > EA . data . str_offset . str - > value . str . len < = T - > EA . data . str_offset . offset ) ) {
2001-06-27 23:40:49 +08:00
zend_error ( E_NOTICE , " Uninitialized string offset: %d " , T - > EA . data . str_offset . offset ) ;
1999-04-08 02:10:10 +08:00
T - > tmp_var . value . str . val = empty_string ;
T - > tmp_var . value . str . len = 0 ;
} else {
2000-04-07 00:34:55 +08:00
char c = str - > value . str . val [ T - > EA . data . str_offset . offset ] ;
1999-04-08 02:10:10 +08:00
T - > tmp_var . value . str . val = estrndup ( & c , 1 ) ;
T - > tmp_var . value . str . len = 1 ;
}
1999-10-28 23:53:31 +08:00
PZVAL_UNLOCK ( str ) ;
1999-04-08 02:10:10 +08:00
T - > tmp_var . refcount = 1 ;
1999-10-02 07:31:39 +08:00
T - > tmp_var . is_ref = 1 ;
1999-04-08 02:10:10 +08:00
T - > tmp_var . type = IS_STRING ;
return & T - > tmp_var ;
}
break ;
}
}
break ;
2003-02-10 01:30:50 +08:00
case IS_UNUSED :
* should_free = 0 ;
return NULL ;
break ;
2000-01-29 05:43:46 +08:00
EMPTY_SWITCH_DEFAULT_CASE ( )
1999-04-08 02:10:10 +08:00
}
return NULL ;
}
2001-07-27 18:10:39 +08:00
static inline zval * * _get_zval_ptr_ptr ( znode * node , temp_variable * Ts TSRMLS_DC )
1999-04-08 02:10:10 +08:00
{
2000-02-02 02:54:01 +08:00
if ( node - > op_type = = IS_VAR ) {
2002-10-24 04:26:28 +08:00
if ( T ( node - > u . var ) . var . ptr_ptr ) {
PZVAL_UNLOCK ( * T ( node - > u . var ) . var . ptr_ptr ) ;
} else if ( T ( node - > u . var ) . EA . type = = IS_STRING_OFFSET ) {
PZVAL_UNLOCK ( T ( node - > u . var ) . EA . data . str_offset . str ) ;
2000-02-02 02:54:01 +08:00
}
2002-10-24 04:26:28 +08:00
return T ( node - > u . var ) . var . ptr_ptr ;
2000-02-02 02:54:01 +08:00
} else {
return NULL ;
1999-04-08 02:10:10 +08:00
}
}
2002-02-07 22:08:43 +08:00
static inline zval * * zend_fetch_property_address_inner ( zval * object , znode * op2 , temp_variable * Ts , int type TSRMLS_DC )
1999-04-08 02:10:10 +08:00
{
2001-01-18 01:34:16 +08:00
zval * prop_ptr = get_zval_ptr ( op2 , Ts , & EG ( free_op2 ) , BP_VAR_R ) ;
2002-09-04 17:07:58 +08:00
zval * * retval = NULL ;
1999-04-08 02:10:10 +08:00
zval tmp ;
switch ( op2 - > op_type ) {
case IS_CONST :
/* already a constant string */
break ;
case IS_VAR :
tmp = * prop_ptr ;
zval_copy_ctor ( & tmp ) ;
convert_to_string ( & tmp ) ;
prop_ptr = & tmp ;
break ;
case IS_TMP_VAR :
convert_to_string ( prop_ptr ) ;
break ;
}
2002-09-15 15:45:26 +08:00
if ( Z_OBJ_HT_P ( object ) - > get_property_ptr ! = NULL ) {
2002-03-10 21:42:37 +08:00
retval = Z_OBJ_HT_P ( object ) - > get_property_ptr ( object , prop_ptr TSRMLS_CC ) ;
2002-09-04 17:07:58 +08:00
}
2002-09-15 15:45:26 +08:00
if ( retval = = NULL ) {
2002-03-10 21:42:37 +08:00
zend_error ( E_WARNING , " This object doesn't support property references " ) ;
retval = & EG ( error_zval_ptr ) ;
}
2002-02-07 22:08:43 +08:00
1999-04-08 02:10:10 +08:00
if ( prop_ptr = = & tmp ) {
zval_dtor ( prop_ptr ) ;
}
2001-10-01 01:29:55 +08:00
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
1999-04-08 02:10:10 +08:00
return retval ;
}
1999-12-23 02:10:38 +08:00
2001-07-27 18:10:39 +08:00
static inline void zend_switch_free ( zend_op * opline , temp_variable * Ts TSRMLS_DC )
1999-12-23 02:10:38 +08:00
{
switch ( opline - > op1 . op_type ) {
case IS_VAR :
2002-10-24 04:26:28 +08:00
if ( ! T ( opline - > op1 . u . var ) . var . ptr_ptr ) {
1999-12-23 02:10:38 +08:00
get_zval_ptr ( & opline - > op1 , Ts , & EG ( free_op1 ) , BP_VAR_R ) ;
2001-10-01 01:29:55 +08:00
FREE_OP ( Ts , & opline - > op1 , EG ( free_op1 ) ) ;
1999-12-23 02:10:38 +08:00
} else {
2002-10-24 04:26:28 +08:00
zval_ptr_dtor ( & T ( opline - > op1 . u . var ) . var . ptr ) ;
2000-01-25 03:04:07 +08:00
if ( opline - > extended_value ) { /* foreach() free */
2002-10-24 04:26:28 +08:00
zval_ptr_dtor ( & T ( opline - > op1 . u . var ) . var . ptr ) ;
2000-01-25 03:04:07 +08:00
}
1999-12-23 02:10:38 +08:00
}
break ;
case IS_TMP_VAR :
2002-10-24 04:26:28 +08:00
zendi_zval_dtor ( T ( opline - > op1 . u . var ) . tmp_var ) ;
1999-12-23 02:10:38 +08:00
break ;
2000-01-29 05:43:46 +08:00
EMPTY_SWITCH_DEFAULT_CASE ( )
1999-12-23 02:10:38 +08:00
}
}
2001-07-27 18:10:39 +08:00
void zend_assign_to_variable_reference ( znode * result , zval * * variable_ptr_ptr , zval * * value_ptr_ptr , temp_variable * Ts TSRMLS_DC )
2001-06-22 05:17:10 +08:00
{
zval * variable_ptr ;
zval * value_ptr ;
if ( ! value_ptr_ptr | | ! variable_ptr_ptr ) {
zend_error ( E_ERROR , " Cannot create references to/from string offsets nor overloaded objects " ) ;
return ;
}
variable_ptr = * variable_ptr_ptr ;
value_ptr = * value_ptr_ptr ;
if ( variable_ptr = = EG ( error_zval_ptr ) | | value_ptr = = EG ( error_zval_ptr ) ) {
variable_ptr_ptr = & EG ( uninitialized_zval_ptr ) ;
2003-02-17 03:18:23 +08:00
} else if ( variable_ptr ! = value_ptr ) {
2001-06-22 05:17:10 +08:00
variable_ptr - > refcount - - ;
if ( variable_ptr - > refcount = = 0 ) {
zendi_zval_dtor ( * variable_ptr ) ;
FREE_ZVAL ( variable_ptr ) ;
}
if ( ! PZVAL_IS_REF ( value_ptr ) ) {
/* break it away */
value_ptr - > refcount - - ;
if ( value_ptr - > refcount > 0 ) {
ALLOC_ZVAL ( * value_ptr_ptr ) ;
* * value_ptr_ptr = * value_ptr ;
value_ptr = * value_ptr_ptr ;
zendi_zval_copy_ctor ( * value_ptr ) ;
}
value_ptr - > refcount = 1 ;
value_ptr - > is_ref = 1 ;
}
* variable_ptr_ptr = value_ptr ;
value_ptr - > refcount + + ;
2003-02-17 03:18:23 +08:00
} else if ( ! variable_ptr - > is_ref ) {
if ( variable_ptr_ptr = = value_ptr_ptr ) {
2003-02-17 02:34:48 +08:00
SEPARATE_ZVAL ( variable_ptr_ptr ) ;
2003-02-17 03:18:23 +08:00
} else if ( variable_ptr = = EG ( uninitialized_zval_ptr )
| | variable_ptr - > refcount > 2 ) {
/* we need to separate */
variable_ptr - > refcount - = 2 ;
ALLOC_ZVAL ( * variable_ptr_ptr ) ;
* * variable_ptr_ptr = * variable_ptr ;
zval_copy_ctor ( * variable_ptr_ptr ) ;
* value_ptr_ptr = * variable_ptr_ptr ;
( * variable_ptr_ptr ) - > refcount = 2 ;
2001-06-22 05:17:10 +08:00
}
( * variable_ptr_ptr ) - > is_ref = 1 ;
}
if ( result & & ! ( result - > u . EA . type & EXT_TYPE_UNUSED ) ) {
2002-10-24 04:26:28 +08:00
T ( result - > u . var ) . var . ptr_ptr = variable_ptr_ptr ;
2001-06-22 05:17:10 +08:00
SELECTIVE_PZVAL_LOCK ( * variable_ptr_ptr , result ) ;
2002-10-24 04:26:28 +08:00
AI_USE_PTR ( T ( result - > u . var ) . var ) ;
2001-06-22 05:17:10 +08:00
}
}
2002-03-11 05:02:00 +08:00
static inline void make_real_object ( zval * * object_ptr TSRMLS_DC )
{
2002-10-17 02:06:36 +08:00
/* this should modify object only if it's empty */
2002-03-10 21:42:37 +08:00
if ( ( * object_ptr ) - > type = = IS_NULL
| | ( ( * object_ptr ) - > type = = IS_BOOL & & ( * object_ptr ) - > value . lval = = 0 )
| | ( ( * object_ptr ) - > type = = IS_STRING & & ( * object_ptr ) - > value . str . len = = 0 ) ) {
if ( ! PZVAL_IS_REF ( * object_ptr ) ) {
SEPARATE_ZVAL ( object_ptr ) ;
}
zend_error ( E_NOTICE , " Creating default object from empty value " ) ;
object_init ( * object_ptr ) ;
}
}
2002-10-17 02:06:36 +08:00
static inline zval * * get_obj_zval_ptr_ptr ( znode * op , temp_variable * Ts , int type TSRMLS_DC )
{
2002-11-30 19:20:25 +08:00
if ( op - > op_type = = IS_UNUSED ) {
if ( EG ( This ) ) {
2002-10-17 02:06:36 +08:00
/* this should actually never be modified, _ptr_ptr is modified only when
the object is empty */
return & EG ( This ) ;
} else {
zend_error ( E_ERROR , " Using $this when not in object context " ) ;
}
}
return get_zval_ptr_ptr ( op , Ts , type ) ;
}
2002-10-23 03:31:53 +08:00
static inline zval * get_obj_zval_ptr ( znode * op , temp_variable * Ts , zval * * freeop , int type TSRMLS_DC )
2002-10-17 02:06:36 +08:00
{
2002-11-30 19:20:25 +08:00
if ( op - > op_type = = IS_UNUSED ) {
if ( EG ( This ) ) {
2002-10-17 02:06:36 +08:00
return EG ( This ) ;
} else {
zend_error ( E_ERROR , " Using $this when not in object context " ) ;
}
}
return get_zval_ptr ( op , Ts , freeop , type ) ;
}
2003-01-27 23:13:01 +08:00
static inline void zend_assign_to_object ( znode * result , znode * op1 , znode * op2 , znode * value_op , temp_variable * Ts TSRMLS_DC )
2002-03-10 21:42:37 +08:00
{
2002-10-17 02:06:36 +08:00
zval * * object_ptr = get_obj_zval_ptr_ptr ( op1 , Ts , BP_VAR_W TSRMLS_CC ) ;
2002-03-10 21:42:37 +08:00
zval * object ;
zval * property = get_zval_ptr ( op2 , Ts , & EG ( free_op2 ) , BP_VAR_R ) ;
2003-01-27 23:13:01 +08:00
zval * free_value ;
zval * value = get_zval_ptr ( value_op , Ts , & free_value , BP_VAR_R ) ;
2002-03-10 21:42:37 +08:00
zval tmp ;
2002-10-24 04:26:28 +08:00
zval * * retval = & T ( result - > u . var ) . var . ptr ;
2002-03-10 21:42:37 +08:00
2002-10-17 02:06:36 +08:00
make_real_object ( object_ptr TSRMLS_CC ) ; /* this should modify object only if it's empty */
2002-03-10 21:42:37 +08:00
object = * object_ptr ;
if ( object - > type ! = IS_OBJECT ) {
zend_error ( E_WARNING , " Attempt to assign property of non-object " ) ;
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
* retval = EG ( uninitialized_zval_ptr ) ;
SELECTIVE_PZVAL_LOCK ( * retval , result ) ;
2002-06-10 17:15:02 +08:00
PZVAL_UNLOCK ( value ) ;
2002-03-10 21:42:37 +08:00
return ;
}
/* here we are sure we are dealing with an object */
switch ( op2 - > op_type ) {
case IS_CONST :
/* already a constant string */
break ;
case IS_VAR :
tmp = * property ;
zval_copy_ctor ( & tmp ) ;
convert_to_string ( & tmp ) ;
property = & tmp ;
break ;
case IS_TMP_VAR :
convert_to_string ( property ) ;
break ;
}
2003-01-12 20:39:06 +08:00
if ( EG ( implicit_clone ) ) {
SEPARATE_ZVAL_IF_NOT_REF ( object_ptr ) ;
object = * object_ptr ;
}
2003-01-29 16:55:12 +08:00
/* by now, property is a string */
2003-01-12 20:39:06 +08:00
2003-01-29 16:55:12 +08:00
/* separate our value if necessary */
if ( value_op - > op_type = = IS_TMP_VAR ) {
zval * orig_value = value ;
ALLOC_ZVAL ( value ) ;
* value = * orig_value ;
value - > is_ref = 0 ;
value - > refcount = 0 ;
}
2002-03-10 21:42:37 +08:00
Z_OBJ_HT_P ( object ) - > write_property ( object , property , value TSRMLS_CC ) ;
if ( property = = & tmp ) {
zval_dtor ( property ) ;
}
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
if ( result ) {
2002-10-24 04:26:28 +08:00
T ( result - > u . var ) . var . ptr = value ;
T ( result - > u . var ) . var . ptr_ptr = NULL ; /* see if we can nuke this */
2002-03-10 21:42:37 +08:00
SELECTIVE_PZVAL_LOCK ( value , result ) ;
}
}
2003-01-27 23:13:01 +08:00
static inline void zend_assign_to_object_op ( znode * result , znode * op1 , znode * op2 , znode * value_op , temp_variable * Ts , int ( * binary_op ) ( zval * result , zval * op1 , zval * op2 TSRMLS_DC ) TSRMLS_DC )
2002-03-11 05:02:00 +08:00
{
2002-11-07 02:51:44 +08:00
zval * * object_ptr = get_obj_zval_ptr_ptr ( op1 , Ts , BP_VAR_W TSRMLS_CC ) ;
2002-03-10 21:42:37 +08:00
zval * object ;
zval * property = get_zval_ptr ( op2 , Ts , & EG ( free_op2 ) , BP_VAR_R ) ;
2003-01-27 23:13:01 +08:00
zval * free_value ;
zval * value = get_zval_ptr ( value_op , Ts , & free_value , BP_VAR_R ) ;
2002-03-10 21:42:37 +08:00
zval tmp ;
2002-10-24 04:26:28 +08:00
zval * * retval = & T ( result - > u . var ) . var . ptr ;
2002-09-04 17:07:58 +08:00
int have_get_ptr = 0 ;
2002-03-10 21:42:37 +08:00
2002-10-24 04:26:28 +08:00
T ( result - > u . var ) . var . ptr_ptr = NULL ;
2002-03-11 05:02:00 +08:00
make_real_object ( object_ptr TSRMLS_CC ) ;
2002-03-10 21:42:37 +08:00
object = * object_ptr ;
if ( object - > type ! = IS_OBJECT ) {
zend_error ( E_WARNING , " Attempt to assign property of non-object " ) ;
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
2003-03-07 00:27:05 +08:00
2002-03-10 21:42:37 +08:00
* retval = EG ( uninitialized_zval_ptr ) ;
SELECTIVE_PZVAL_LOCK ( * retval , result ) ;
return ;
}
/* here we are sure we are dealing with an object */
switch ( op2 - > op_type ) {
case IS_CONST :
/* already a constant string */
break ;
case IS_VAR :
tmp = * property ;
zval_copy_ctor ( & tmp ) ;
convert_to_string ( & tmp ) ;
property = & tmp ;
break ;
case IS_TMP_VAR :
convert_to_string ( property ) ;
break ;
}
/* here property is a string */
2002-09-15 15:45:26 +08:00
if ( Z_OBJ_HT_P ( object ) - > get_property_zval_ptr ) {
2002-03-10 21:42:37 +08:00
zval * * zptr = Z_OBJ_HT_P ( object ) - > get_property_zval_ptr ( object , property TSRMLS_CC ) ;
2002-09-15 15:45:26 +08:00
if ( zptr ! = NULL ) { /* NULL means no success in getting PTR */
2002-09-04 17:07:58 +08:00
SEPARATE_ZVAL_IF_NOT_REF ( zptr ) ;
2002-03-10 21:42:37 +08:00
2002-09-04 17:07:58 +08:00
have_get_ptr = 1 ;
binary_op ( * zptr , * zptr , value TSRMLS_CC ) ;
* retval = * zptr ;
SELECTIVE_PZVAL_LOCK ( * retval , result ) ;
}
}
2002-09-15 15:45:26 +08:00
if ( ! have_get_ptr ) {
2003-02-05 22:27:30 +08:00
zval * z = Z_OBJ_HT_P ( object ) - > read_property ( object , property TSRMLS_CC ) ;
2002-03-10 21:42:37 +08:00
SEPARATE_ZVAL_IF_NOT_REF ( & z ) ;
2002-03-11 05:02:00 +08:00
binary_op ( z , z , value TSRMLS_CC ) ;
2002-03-10 21:42:37 +08:00
Z_OBJ_HT_P ( object ) - > write_property ( object , property , z TSRMLS_CC ) ;
* retval = z ;
SELECTIVE_PZVAL_LOCK ( * retval , result ) ;
2002-09-15 15:45:26 +08:00
if ( z - > refcount < = 1 ) {
2002-03-10 21:42:37 +08:00
zval_dtor ( z ) ;
}
}
if ( property = = & tmp ) {
zval_dtor ( property ) ;
}
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
}
1999-12-23 02:10:38 +08:00
2001-07-27 18:10:39 +08:00
static inline void zend_assign_to_variable ( znode * result , znode * op1 , znode * op2 , zval * value , int type , temp_variable * Ts TSRMLS_DC )
1999-04-08 02:10:10 +08:00
{
zval * * variable_ptr_ptr = get_zval_ptr_ptr ( op1 , Ts , BP_VAR_W ) ;
zval * variable_ptr ;
1999-10-02 07:26:00 +08:00
1999-04-08 02:10:10 +08:00
if ( ! variable_ptr_ptr ) {
2002-10-24 04:26:28 +08:00
switch ( T ( op1 - > u . var ) . EA . type ) {
1999-04-08 02:10:10 +08:00
case IS_STRING_OFFSET : {
2002-10-24 04:26:28 +08:00
temp_variable * T = & T ( op1 - > u . var ) ;
1999-04-08 02:10:10 +08:00
2001-06-27 23:40:49 +08:00
if ( T - > EA . data . str_offset . str - > type = = IS_STRING ) do {
1999-04-08 02:10:10 +08:00
zval tmp ;
1999-09-19 06:07:12 +08:00
zval * final_value = value ;
1999-04-08 02:10:10 +08:00
2003-05-05 03:11:48 +08:00
if ( ( ( int ) T - > EA . data . str_offset . offset < 0 ) ) {
2001-06-27 23:40:49 +08:00
zend_error ( E_WARNING , " Illegal string offset: %d " , T - > EA . data . str_offset . offset ) ;
break ;
}
if ( T - > EA . data . str_offset . offset > = T - > EA . data . str_offset . str - > value . str . len ) {
2002-04-24 02:06:54 +08:00
zend_uint i ;
2001-06-27 23:40:49 +08:00
if ( T - > EA . data . str_offset . str - > value . str . len = = 0 ) {
2001-06-27 23:47:31 +08:00
STR_FREE ( T - > EA . data . str_offset . str - > value . str . val ) ;
2001-06-27 23:40:49 +08:00
T - > EA . data . str_offset . str - > value . str . val = ( char * ) emalloc ( T - > EA . data . str_offset . offset + 1 + 1 ) ;
} else {
T - > EA . data . str_offset . str - > value . str . val = ( char * ) erealloc ( T - > EA . data . str_offset . str - > value . str . val , T - > EA . data . str_offset . offset + 1 + 1 ) ;
}
for ( i = T - > EA . data . str_offset . str - > value . str . len ; i < T - > EA . data . str_offset . offset ; i + + ) {
T - > EA . data . str_offset . str - > value . str . val [ i ] = ' ' ;
}
T - > EA . data . str_offset . str - > value . str . val [ T - > EA . data . str_offset . offset + 1 ] = 0 ;
T - > EA . data . str_offset . str - > value . str . len = T - > EA . data . str_offset . offset + 1 ;
}
1999-04-08 02:10:10 +08:00
if ( value - > type ! = IS_STRING ) {
tmp = * value ;
1999-09-19 06:07:12 +08:00
if ( op2 & & op2 - > op_type = = IS_VAR ) {
zval_copy_ctor ( & tmp ) ;
}
1999-04-08 02:10:10 +08:00
convert_to_string ( & tmp ) ;
1999-09-19 06:07:12 +08:00
final_value = & tmp ;
1999-04-08 02:10:10 +08:00
}
2000-04-07 00:34:55 +08:00
T - > EA . data . str_offset . str - > value . str . val [ T - > EA . data . str_offset . offset ] = final_value - > value . str . val [ 0 ] ;
2003-03-07 08:28:25 +08:00
if ( op2 ) {
if ( op2 - > op_type = = IS_VAR ) {
if ( value = = & T ( op2 - > u . var ) . tmp_var ) {
STR_FREE ( value - > value . str . val ) ;
}
} else {
if ( final_value = = & T ( op2 - > u . var ) . tmp_var ) {
/* we can safely free final_value here
* because separation is done only
* in case op2 - > op_type = = IS_VAR */
STR_FREE ( final_value - > value . str . val ) ;
}
}
1999-06-01 02:33:12 +08:00
}
1999-09-19 06:07:12 +08:00
if ( final_value = = & tmp ) {
zval_dtor ( final_value ) ;
1999-04-08 02:10:10 +08:00
}
/*
* the value of an assignment to a string offset is undefined
2002-10-24 04:26:28 +08:00
T ( result - > u . var ) . var = & T - > EA . data . str_offset . str ;
1999-04-08 02:10:10 +08:00
*/
2002-09-15 15:46:20 +08:00
} while ( 0 ) ;
2000-04-07 00:34:55 +08:00
/* zval_ptr_dtor(&T->EA.data.str_offset.str); Nuke this line if it doesn't cause a leak */
1999-04-08 02:10:10 +08:00
T - > tmp_var . type = IS_STRING ;
}
break ;
2000-01-29 05:43:46 +08:00
EMPTY_SWITCH_DEFAULT_CASE ( )
1999-04-08 02:10:10 +08:00
}
2002-10-24 04:26:28 +08:00
T ( result - > u . var ) . var . ptr_ptr = & EG ( uninitialized_zval_ptr ) ;
SELECTIVE_PZVAL_LOCK ( * T ( result - > u . var ) . var . ptr_ptr , result ) ;
AI_USE_PTR ( T ( result - > u . var ) . var ) ;
1999-04-08 02:10:10 +08:00
return ;
}
variable_ptr = * variable_ptr_ptr ;
if ( variable_ptr = = EG ( error_zval_ptr ) ) {
if ( result ) {
2002-10-24 04:26:28 +08:00
T ( result - > u . var ) . var . ptr_ptr = & EG ( uninitialized_zval_ptr ) ;
SELECTIVE_PZVAL_LOCK ( * T ( result - > u . var ) . var . ptr_ptr , result ) ;
AI_USE_PTR ( T ( result - > u . var ) . var ) ;
1999-04-08 02:10:10 +08:00
}
2000-01-19 06:18:17 +08:00
if ( type = = IS_TMP_VAR ) {
zval_dtor ( value ) ;
}
1999-04-08 02:10:10 +08:00
return ;
}
1999-07-10 02:19:48 +08:00
if ( PZVAL_IS_REF ( variable_ptr ) ) {
1999-04-08 02:10:10 +08:00
if ( variable_ptr ! = value ) {
2002-04-24 02:06:54 +08:00
zend_uint refcount = variable_ptr - > refcount ;
2000-02-09 04:10:47 +08:00
zval garbage ;
1999-04-08 02:10:10 +08:00
1999-07-13 02:07:01 +08:00
if ( type ! = IS_TMP_VAR ) {
value - > refcount + + ;
}
2000-02-09 04:10:47 +08:00
garbage = * variable_ptr ;
1999-04-08 02:10:10 +08:00
* variable_ptr = * value ;
variable_ptr - > refcount = refcount ;
1999-10-02 07:31:39 +08:00
variable_ptr - > is_ref = 1 ;
1999-04-08 02:10:10 +08:00
if ( type ! = IS_TMP_VAR ) {
zendi_zval_copy_ctor ( * variable_ptr ) ;
2000-01-25 01:29:15 +08:00
value - > refcount - - ;
1999-04-08 02:10:10 +08:00
}
2000-02-09 04:10:47 +08:00
zendi_zval_dtor ( garbage ) ;
1999-04-08 02:10:10 +08:00
}
} else {
1999-05-29 20:00:32 +08:00
variable_ptr - > refcount - - ;
1999-04-08 02:10:10 +08:00
if ( variable_ptr - > refcount = = 0 ) {
switch ( type ) {
case IS_VAR :
1999-08-24 03:02:28 +08:00
/* break missing intentionally */
1999-04-08 02:10:10 +08:00
case IS_CONST :
if ( variable_ptr = = value ) {
variable_ptr - > refcount + + ;
1999-07-10 02:19:48 +08:00
} else if ( PZVAL_IS_REF ( value ) ) {
2001-01-27 20:29:02 +08:00
zval tmp ;
1999-06-10 05:39:12 +08:00
tmp = * value ;
zval_copy_ctor ( & tmp ) ;
tmp . refcount = 1 ;
1999-05-29 20:00:32 +08:00
zendi_zval_dtor ( * variable_ptr ) ;
1999-06-10 05:39:12 +08:00
* variable_ptr = tmp ;
1999-04-08 02:10:10 +08:00
} else {
1999-06-10 05:39:12 +08:00
value - > refcount + + ;
1999-04-08 02:10:10 +08:00
zendi_zval_dtor ( * variable_ptr ) ;
safe_free_zval_ptr ( variable_ptr ) ;
* variable_ptr_ptr = value ;
}
break ;
case IS_TMP_VAR :
zendi_zval_dtor ( * variable_ptr ) ;
value - > refcount = 1 ;
* variable_ptr = * value ;
break ;
2000-01-29 05:43:46 +08:00
EMPTY_SWITCH_DEFAULT_CASE ( )
1999-04-08 02:10:10 +08:00
}
} else { /* we need to split */
switch ( type ) {
case IS_VAR :
1999-08-24 03:02:28 +08:00
/* break missing intentionally */
1999-04-08 02:10:10 +08:00
case IS_CONST :
1999-12-16 04:15:32 +08:00
if ( PZVAL_IS_REF ( value ) & & value - > refcount > 0 ) {
1999-12-27 05:21:33 +08:00
ALLOC_ZVAL ( variable_ptr ) ;
* variable_ptr_ptr = variable_ptr ;
1999-04-08 02:10:10 +08:00
* variable_ptr = * value ;
zval_copy_ctor ( variable_ptr ) ;
variable_ptr - > refcount = 1 ;
break ;
}
* variable_ptr_ptr = value ;
value - > refcount + + ;
break ;
case IS_TMP_VAR :
1999-12-27 05:21:33 +08:00
ALLOC_ZVAL ( * variable_ptr_ptr ) ;
1999-04-08 02:10:10 +08:00
value - > refcount = 1 ;
* * variable_ptr_ptr = * value ;
break ;
2000-01-29 05:43:46 +08:00
EMPTY_SWITCH_DEFAULT_CASE ( )
1999-04-08 02:10:10 +08:00
}
}
1999-10-02 07:31:39 +08:00
( * variable_ptr_ptr ) - > is_ref = 0 ;
1999-04-08 02:10:10 +08:00
}
if ( result ) {
2002-10-24 04:26:28 +08:00
T ( result - > u . var ) . var . ptr_ptr = variable_ptr_ptr ;
1999-07-10 17:29:02 +08:00
SELECTIVE_PZVAL_LOCK ( * variable_ptr_ptr , result ) ;
2002-10-24 04:26:28 +08:00
AI_USE_PTR ( T ( result - > u . var ) . var ) ;
1999-07-10 04:43:59 +08:00
}
1999-04-08 02:10:10 +08:00
}
/* Utility Functions for Extensions */
2001-07-31 12:53:54 +08:00
static void zend_extension_statement_handler ( zend_extension * extension , zend_op_array * op_array TSRMLS_DC )
1999-04-08 02:10:10 +08:00
{
if ( extension - > statement_handler ) {
extension - > statement_handler ( op_array ) ;
}
}
2001-07-31 12:53:54 +08:00
static void zend_extension_fcall_begin_handler ( zend_extension * extension , zend_op_array * op_array TSRMLS_DC )
1999-04-08 02:10:10 +08:00
{
if ( extension - > fcall_begin_handler ) {
extension - > fcall_begin_handler ( op_array ) ;
}
}
2001-07-31 12:53:54 +08:00
static void zend_extension_fcall_end_handler ( zend_extension * extension , zend_op_array * op_array TSRMLS_DC )
1999-04-08 02:10:10 +08:00
{
if ( extension - > fcall_end_handler ) {
extension - > fcall_end_handler ( op_array ) ;
}
}
static void print_refcount ( zval * p , char * str )
{
print_refcount ( NULL , NULL ) ;
}
2002-10-17 02:29:41 +08:00
static inline HashTable * zend_get_target_symbol_table ( zend_op * opline , temp_variable * Ts , int type , zval * variable TSRMLS_DC )
1999-04-08 02:10:10 +08:00
{
2002-01-06 03:59:09 +08:00
switch ( opline - > op2 . u . EA . type ) {
1999-04-08 02:10:10 +08:00
case ZEND_FETCH_LOCAL :
2002-02-05 03:29:56 +08:00
return EG ( active_symbol_table ) ;
1999-04-08 02:10:10 +08:00
break ;
case ZEND_FETCH_GLOBAL :
2002-02-07 22:08:43 +08:00
/* Don't think this is actually needed.
if ( opline - > op1 . op_type = = IS_VAR ) {
1999-07-10 18:55:55 +08:00
PZVAL_LOCK ( varname ) ;
1999-06-06 02:47:36 +08:00
}
2002-02-07 22:08:43 +08:00
+ */
2002-02-05 03:29:56 +08:00
return & EG ( symbol_table ) ;
1999-04-08 02:10:10 +08:00
break ;
case ZEND_FETCH_STATIC :
1999-04-08 08:18:29 +08:00
if ( ! EG ( active_op_array ) - > static_variables ) {
1999-12-28 03:07:33 +08:00
ALLOC_HASHTABLE ( EG ( active_op_array ) - > static_variables ) ;
1999-12-22 01:14:31 +08:00
zend_hash_init ( EG ( active_op_array ) - > static_variables , 2 , NULL , ZVAL_PTR_DTOR , 0 ) ;
1999-04-08 08:18:29 +08:00
}
2002-02-05 03:29:56 +08:00
return EG ( active_op_array ) - > static_variables ;
1999-04-08 02:10:10 +08:00
break ;
2000-01-29 05:43:46 +08:00
EMPTY_SWITCH_DEFAULT_CASE ( )
1999-04-08 02:10:10 +08:00
}
2002-02-07 22:08:43 +08:00
return NULL ;
2002-02-05 03:29:56 +08:00
}
static void zend_fetch_var_address ( zend_op * opline , temp_variable * Ts , int type TSRMLS_DC )
{
2002-10-23 03:31:53 +08:00
zval * free_op1 ;
2002-02-05 03:29:56 +08:00
zval * varname = get_zval_ptr ( & opline - > op1 , Ts , & free_op1 , BP_VAR_R ) ;
zval * * retval ;
zval tmp_varname ;
HashTable * target_symbol_table ;
2002-01-06 03:59:09 +08:00
if ( varname - > type ! = IS_STRING ) {
1999-04-08 02:10:10 +08:00
tmp_varname = * varname ;
zval_copy_ctor ( & tmp_varname ) ;
convert_to_string ( & tmp_varname ) ;
varname = & tmp_varname ;
}
2002-02-05 03:29:56 +08:00
2003-02-05 21:35:52 +08:00
if ( opline - > op2 . u . EA . type = = ZEND_FETCH_STATIC_MEMBER ) {
target_symbol_table = NULL ;
2003-02-17 22:06:39 +08:00
retval = zend_std_get_static_property ( T ( opline - > op2 . u . var ) . EA . class_entry , Z_STRVAL_P ( varname ) , Z_STRLEN_P ( varname ) , 0 TSRMLS_CC ) ;
2003-02-05 21:35:52 +08:00
} else {
target_symbol_table = zend_get_target_symbol_table ( opline , Ts , type , varname TSRMLS_CC ) ;
if ( ! target_symbol_table ) {
return ;
}
if ( zend_hash_find ( target_symbol_table , varname - > value . str . val , varname - > value . str . len + 1 , ( void * * ) & retval ) = = FAILURE ) {
switch ( type ) {
case BP_VAR_R :
zend_error ( E_NOTICE , " Undefined variable: %s " , varname - > value . str . val ) ;
/* break missing intentionally */
case BP_VAR_IS :
retval = & EG ( uninitialized_zval_ptr ) ;
break ;
case BP_VAR_RW :
zend_error ( E_NOTICE , " Undefined variable: %s " , varname - > value . str . val ) ;
/* break missing intentionally */
case BP_VAR_W : {
zval * new_zval = & EG ( uninitialized_zval ) ;
2002-10-17 02:29:41 +08:00
2003-02-05 21:35:52 +08:00
new_zval - > refcount + + ;
zend_hash_update ( target_symbol_table , varname - > value . str . val , varname - > value . str . len + 1 , & new_zval , sizeof ( zval * ) , ( void * * ) & retval ) ;
}
break ;
EMPTY_SWITCH_DEFAULT_CASE ( )
}
}
switch ( opline - > op2 . u . EA . type ) {
case ZEND_FETCH_LOCAL :
FREE_OP ( Ts , & opline - > op1 , free_op1 ) ;
1999-04-08 02:10:10 +08:00
break ;
2003-02-05 21:35:52 +08:00
case ZEND_FETCH_STATIC :
zval_update_constant ( retval , ( void * ) 1 TSRMLS_CC ) ;
1999-04-08 02:10:10 +08:00
break ;
}
}
2003-02-05 21:35:52 +08:00
1999-04-08 02:10:10 +08:00
if ( varname = = & tmp_varname ) {
zval_dtor ( varname ) ;
}
2002-10-24 04:26:28 +08:00
T ( opline - > result . u . var ) . var . ptr_ptr = retval ;
2001-11-25 02:27:20 +08:00
SELECTIVE_PZVAL_LOCK ( * retval , & opline - > result ) ;
1999-04-08 02:10:10 +08:00
}
2001-07-27 18:10:39 +08:00
static inline zval * * zend_fetch_dimension_address_inner ( HashTable * ht , znode * op2 , temp_variable * Ts , int type TSRMLS_DC )
1999-04-08 02:10:10 +08:00
{
2001-01-18 01:34:16 +08:00
zval * dim = get_zval_ptr ( op2 , Ts , & EG ( free_op2 ) , BP_VAR_R ) ;
1999-04-08 02:10:10 +08:00
zval * * retval ;
2000-01-04 01:26:24 +08:00
char * offset_key ;
int offset_key_length ;
1999-04-08 02:10:10 +08:00
switch ( dim - > type ) {
2000-01-04 21:22:58 +08:00
case IS_NULL :
2000-01-04 01:26:24 +08:00
offset_key = " " ;
offset_key_length = 0 ;
goto fetch_string_dim ;
case IS_STRING :
offset_key = dim - > value . str . val ;
offset_key_length = dim - > value . str . len ;
fetch_string_dim :
if ( zend_hash_find ( ht , offset_key , offset_key_length + 1 , ( void * * ) & retval ) = = FAILURE ) {
switch ( type ) {
case BP_VAR_R :
zend_error ( E_NOTICE , " Undefined index: %s " , offset_key ) ;
/* break missing intentionally */
case BP_VAR_IS :
retval = & EG ( uninitialized_zval_ptr ) ;
break ;
case BP_VAR_RW :
zend_error ( E_NOTICE , " Undefined index: %s " , offset_key ) ;
/* break missing intentionally */
case BP_VAR_W : {
zval * new_zval = & EG ( uninitialized_zval ) ;
new_zval - > refcount + + ;
2000-03-24 19:12:30 +08:00
zend_hash_update ( ht , offset_key , offset_key_length + 1 , & new_zval , sizeof ( zval * ) , ( void * * ) & retval ) ;
2000-01-04 01:26:24 +08:00
}
break ;
1999-04-08 02:10:10 +08:00
}
}
break ;
1999-09-09 04:38:08 +08:00
case IS_DOUBLE :
1999-10-06 23:09:26 +08:00
case IS_RESOURCE :
2000-01-19 06:18:17 +08:00
case IS_BOOL :
1999-04-08 02:10:10 +08:00
case IS_LONG : {
1999-09-09 04:38:08 +08:00
long index ;
2000-01-19 06:18:17 +08:00
if ( dim - > type = = IS_DOUBLE ) {
1999-09-09 04:38:08 +08:00
index = ( long ) dim - > value . dval ;
2000-01-19 06:18:17 +08:00
} else {
index = dim - > value . lval ;
1999-09-09 04:38:08 +08:00
}
if ( zend_hash_index_find ( ht , index , ( void * * ) & retval ) = = FAILURE ) {
1999-04-08 02:10:10 +08:00
switch ( type ) {
case BP_VAR_R :
1999-09-09 04:38:08 +08:00
zend_error ( E_NOTICE , " Undefined offset: %d " , index ) ;
1999-04-08 02:10:10 +08:00
/* break missing intentionally */
case BP_VAR_IS :
retval = & EG ( uninitialized_zval_ptr ) ;
break ;
case BP_VAR_RW :
1999-09-09 04:38:08 +08:00
zend_error ( E_NOTICE , " Undefined offset: %d " , index ) ;
1999-04-08 02:10:10 +08:00
/* break missing intentionally */
case BP_VAR_W : {
1999-05-21 04:00:59 +08:00
zval * new_zval = & EG ( uninitialized_zval ) ;
1999-04-08 02:10:10 +08:00
1999-05-21 04:00:59 +08:00
new_zval - > refcount + + ;
1999-09-09 04:38:08 +08:00
zend_hash_index_update ( ht , index , & new_zval , sizeof ( zval * ) , ( void * * ) & retval ) ;
1999-04-08 02:10:10 +08:00
}
break ;
}
}
}
break ;
default :
zend_error ( E_WARNING , " Illegal offset type " ) ;
if ( type = = BP_VAR_R | | type = = BP_VAR_IS ) {
retval = & EG ( uninitialized_zval_ptr ) ;
} else {
retval = & EG ( error_zval_ptr ) ;
}
break ;
}
2001-10-01 01:29:55 +08:00
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
1999-04-08 02:10:10 +08:00
return retval ;
}
2001-07-27 18:10:39 +08:00
static void zend_fetch_dimension_address ( znode * result , znode * op1 , znode * op2 , temp_variable * Ts , int type TSRMLS_DC )
1999-04-08 02:10:10 +08:00
{
zval * * container_ptr = get_zval_ptr_ptr ( op1 , Ts , type ) ;
zval * container ;
2002-10-24 04:26:28 +08:00
zval * * * retval = & T ( result - > u . var ) . var . ptr_ptr ;
1999-04-08 02:10:10 +08:00
2002-11-13 23:13:24 +08:00
if ( ! container_ptr ) {
2002-11-30 19:20:25 +08:00
if ( T ( op1 - > u . var ) . EA . type = = IS_STRING_OFFSET ) {
2002-11-18 01:57:57 +08:00
zval * offset ;
2002-11-13 23:13:24 +08:00
zend_error ( E_WARNING , " Cannot use string offset as an array " ) ;
2002-11-18 01:57:57 +08:00
offset = get_zval_ptr ( op2 , Ts , & EG ( free_op2 ) , BP_VAR_R ) ;
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
2002-11-13 23:13:24 +08:00
}
* retval = & EG ( error_zval_ptr ) ;
SELECTIVE_PZVAL_LOCK ( * * retval , result ) ;
return ;
}
1999-04-08 02:10:10 +08:00
container = * container_ptr ;
if ( container = = EG ( error_zval_ptr ) ) {
* retval = & EG ( error_zval_ptr ) ;
1999-07-11 02:46:20 +08:00
SELECTIVE_PZVAL_LOCK ( * * retval , result ) ;
1999-04-08 02:10:10 +08:00
return ;
}
2000-01-10 03:16:34 +08:00
if ( container - > type = = IS_NULL
2000-03-18 22:28:03 +08:00
| | ( container - > type = = IS_BOOL & & container - > value . lval = = 0 )
2000-01-10 03:16:34 +08:00
| | ( container - > type = = IS_STRING & & container - > value . str . len = = 0 ) ) {
1999-04-08 02:10:10 +08:00
switch ( type ) {
case BP_VAR_RW :
case BP_VAR_W :
1999-07-10 02:19:48 +08:00
if ( ! PZVAL_IS_REF ( container ) ) {
2000-08-05 21:54:07 +08:00
SEPARATE_ZVAL ( container_ptr ) ;
container = * container_ptr ;
1999-04-08 02:10:10 +08:00
}
array_init ( container ) ;
break ;
}
}
switch ( container - > type ) {
case IS_ARRAY :
1999-07-10 02:19:48 +08:00
if ( ( type = = BP_VAR_W | | type = = BP_VAR_RW ) & & container - > refcount > 1 & & ! PZVAL_IS_REF ( container ) ) {
2000-08-05 21:54:07 +08:00
SEPARATE_ZVAL ( container_ptr ) ;
1999-04-08 02:10:10 +08:00
container = * container_ptr ;
}
if ( op2 - > op_type = = IS_UNUSED ) {
1999-05-21 04:00:59 +08:00
zval * new_zval = & EG ( uninitialized_zval ) ;
1999-04-08 02:10:10 +08:00
1999-05-21 04:00:59 +08:00
new_zval - > refcount + + ;
2002-08-02 00:07:19 +08:00
if ( zend_hash_next_index_insert ( container - > value . ht , & new_zval , sizeof ( zval * ) , ( void * * ) retval ) = = FAILURE ) {
2002-11-12 02:27:32 +08:00
zend_error ( E_WARNING , " Cannot add element to the array as the next element is already occupied " ) ;
2002-08-02 00:07:19 +08:00
* retval = & EG ( uninitialized_zval_ptr ) ;
new_zval - > refcount - - ;
}
1999-04-08 02:10:10 +08:00
} else {
2001-07-27 18:10:39 +08:00
* retval = zend_fetch_dimension_address_inner ( container - > value . ht , op2 , Ts , type TSRMLS_CC ) ;
1999-04-08 02:10:10 +08:00
}
1999-07-10 17:29:02 +08:00
SELECTIVE_PZVAL_LOCK ( * * retval , result ) ;
1999-04-08 02:10:10 +08:00
break ;
2000-01-04 21:22:58 +08:00
case IS_NULL :
1999-12-31 21:56:59 +08:00
/* for read-mode only */
2001-01-18 01:34:16 +08:00
get_zval_ptr ( op2 , Ts , & EG ( free_op2 ) , BP_VAR_R ) ;
1999-12-31 21:56:59 +08:00
* retval = & EG ( uninitialized_zval_ptr ) ;
SELECTIVE_PZVAL_LOCK ( * * retval , result ) ;
2001-10-01 01:29:55 +08:00
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
2000-04-12 01:38:19 +08:00
if ( type = = BP_VAR_W | | type = = BP_VAR_RW ) {
zend_error ( E_WARNING , " Cannot use a NULL value as an array " ) ;
}
1999-12-31 21:56:59 +08:00
break ;
1999-04-08 02:10:10 +08:00
case IS_STRING : {
zval * offset ;
1999-12-31 21:56:59 +08:00
zval tmp ;
1999-04-08 02:10:10 +08:00
2000-01-04 04:01:54 +08:00
if ( op2 - > op_type = = IS_UNUSED ) {
zend_error ( E_ERROR , " [] operator not supported for strings " ) ;
}
2001-01-18 01:34:16 +08:00
offset = get_zval_ptr ( op2 , Ts , & EG ( free_op2 ) , BP_VAR_R ) ;
1999-04-08 02:10:10 +08:00
1999-12-31 21:56:59 +08:00
if ( offset - > type ! = IS_LONG ) {
tmp = * offset ;
zval_copy_ctor ( & tmp ) ;
convert_to_long ( & tmp ) ;
offset = & tmp ;
}
2000-02-17 00:00:02 +08:00
if ( type ! = BP_VAR_R & & type ! = BP_VAR_IS ) {
SEPARATE_ZVAL_IF_NOT_REF ( container_ptr ) ;
1999-04-08 02:10:10 +08:00
}
1999-12-31 21:56:59 +08:00
container = * container_ptr ;
2002-10-24 04:26:28 +08:00
T ( result - > u . var ) . EA . data . str_offset . str = container ;
1999-12-31 21:56:59 +08:00
PZVAL_LOCK ( container ) ;
2002-10-24 04:26:28 +08:00
T ( result - > u . var ) . EA . data . str_offset . offset = offset - > value . lval ;
T ( result - > u . var ) . EA . type = IS_STRING_OFFSET ;
2001-10-01 01:29:55 +08:00
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
1999-12-31 21:56:59 +08:00
* retval = NULL ;
return ;
1999-04-08 02:10:10 +08:00
}
break ;
default : {
zval * offset ;
2001-01-18 01:34:16 +08:00
offset = get_zval_ptr ( op2 , Ts , & EG ( free_op2 ) , BP_VAR_R ) ;
1999-04-08 02:10:10 +08:00
if ( type = = BP_VAR_R | | type = = BP_VAR_IS ) {
* retval = & EG ( uninitialized_zval_ptr ) ;
} else {
* retval = & EG ( error_zval_ptr ) ;
}
2001-10-01 01:29:55 +08:00
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
1999-07-11 02:46:20 +08:00
SELECTIVE_PZVAL_LOCK ( * * retval , result ) ;
2000-04-12 01:38:19 +08:00
if ( type = = BP_VAR_W | | type = = BP_VAR_RW ) {
zend_error ( E_WARNING , " Cannot use a scalar value as an array " ) ;
}
1999-04-08 02:10:10 +08:00
}
break ;
}
}
2001-07-27 18:10:39 +08:00
static void zend_fetch_dimension_address_from_tmp_var ( znode * result , znode * op1 , znode * op2 , temp_variable * Ts TSRMLS_DC )
1999-04-08 02:10:10 +08:00
{
2002-10-23 03:31:53 +08:00
zval * free_op1 ;
1999-04-08 02:10:10 +08:00
zval * container = get_zval_ptr ( op1 , Ts , & free_op1 , BP_VAR_R ) ;
if ( container - > type ! = IS_ARRAY ) {
2002-10-24 04:26:28 +08:00
T ( result - > u . var ) . var . ptr_ptr = & EG ( uninitialized_zval_ptr ) ;
SELECTIVE_PZVAL_LOCK ( * T ( result - > u . var ) . var . ptr_ptr , result ) ;
1999-04-08 02:10:10 +08:00
return ;
}
2002-10-24 04:26:28 +08:00
T ( result - > u . var ) . var . ptr_ptr = zend_fetch_dimension_address_inner ( container - > value . ht , op2 , Ts , BP_VAR_R TSRMLS_CC ) ;
SELECTIVE_PZVAL_LOCK ( * T ( result - > u . var ) . var . ptr_ptr , result ) ;
1999-04-08 02:10:10 +08:00
}
2001-07-27 18:10:39 +08:00
static void zend_fetch_property_address ( znode * result , znode * op1 , znode * op2 , temp_variable * Ts , int type TSRMLS_DC )
1999-04-08 02:10:10 +08:00
{
2002-10-17 03:16:58 +08:00
zval * * container_ptr = get_obj_zval_ptr_ptr ( op1 , Ts , type TSRMLS_CC ) ;
1999-04-08 02:10:10 +08:00
zval * container ;
2002-10-24 04:26:28 +08:00
zval * * * retval = & T ( result - > u . var ) . var . ptr_ptr ;
2002-02-07 22:08:43 +08:00
1999-04-08 02:10:10 +08:00
container = * container_ptr ;
if ( container = = EG ( error_zval_ptr ) ) {
* retval = & EG ( error_zval_ptr ) ;
1999-07-11 02:46:20 +08:00
SELECTIVE_PZVAL_LOCK ( * * retval , result ) ;
1999-04-08 02:10:10 +08:00
return ;
}
2002-10-17 02:06:36 +08:00
/* this should modify object only if it's empty */
2002-02-07 22:08:43 +08:00
if ( container - > type = = IS_NULL
| | ( container - > type = = IS_BOOL & & container - > value . lval = = 0 )
| | ( container - > type = = IS_STRING & & container - > value . str . len = = 0 ) ) {
1999-04-08 02:10:10 +08:00
switch ( type ) {
case BP_VAR_RW :
case BP_VAR_W :
1999-07-10 02:19:48 +08:00
if ( ! PZVAL_IS_REF ( container ) ) {
2000-08-05 21:54:07 +08:00
SEPARATE_ZVAL ( container_ptr ) ;
container = * container_ptr ;
1999-04-08 02:10:10 +08:00
}
object_init ( container ) ;
break ;
}
}
2002-02-07 22:08:43 +08:00
1999-04-08 02:10:10 +08:00
if ( container - > type ! = IS_OBJECT ) {
zval * offset ;
2002-02-07 22:08:43 +08:00
2001-01-18 01:34:16 +08:00
offset = get_zval_ptr ( op2 , Ts , & EG ( free_op2 ) , BP_VAR_R ) ;
2001-10-01 01:29:55 +08:00
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
2002-02-07 22:08:43 +08:00
if ( type = = BP_VAR_R | | type = = BP_VAR_IS ) {
1999-04-08 02:10:10 +08:00
* retval = & EG ( uninitialized_zval_ptr ) ;
} else {
* retval = & EG ( error_zval_ptr ) ;
}
1999-10-03 02:02:10 +08:00
SELECTIVE_PZVAL_LOCK ( * * retval , result ) ;
return ;
1999-04-08 02:10:10 +08:00
}
2002-02-07 22:08:43 +08:00
1999-07-10 02:19:48 +08:00
if ( ( type = = BP_VAR_W | | type = = BP_VAR_RW ) & & container - > refcount > 1 & & ! PZVAL_IS_REF ( container ) ) {
2000-08-05 21:54:07 +08:00
SEPARATE_ZVAL ( container_ptr ) ;
1999-04-08 02:10:10 +08:00
container = * container_ptr ;
}
2002-02-07 22:08:43 +08:00
* retval = zend_fetch_property_address_inner ( container , op2 , Ts , type TSRMLS_CC ) ;
1999-07-10 17:29:02 +08:00
SELECTIVE_PZVAL_LOCK ( * * retval , result ) ;
1999-04-08 02:10:10 +08:00
}
2002-02-07 22:08:43 +08:00
static void zend_fetch_property_address_read ( znode * result , znode * op1 , znode * op2 , temp_variable * Ts , int type TSRMLS_DC )
1999-04-08 02:10:10 +08:00
{
2002-02-07 22:08:43 +08:00
zval * container ;
zval * * retval ;
1999-04-08 02:10:10 +08:00
2002-10-24 04:26:28 +08:00
retval = & T ( result - > u . var ) . var . ptr ;
T ( result - > u . var ) . var . ptr_ptr = retval ;
1999-04-08 02:10:10 +08:00
2002-10-17 03:16:58 +08:00
container = get_obj_zval_ptr ( op1 , Ts , & EG ( free_op1 ) , type TSRMLS_CC ) ;
2001-08-06 10:52:03 +08:00
2002-02-07 22:08:43 +08:00
if ( container = = EG ( error_zval_ptr ) ) {
* retval = EG ( error_zval_ptr ) ;
SELECTIVE_PZVAL_LOCK ( * retval , result ) ;
return ;
2001-05-03 03:51:33 +08:00
}
1999-04-08 02:10:10 +08:00
2002-02-07 22:08:43 +08:00
2002-09-15 15:45:26 +08:00
if ( container - > type ! = IS_OBJECT ) {
2002-02-07 22:08:43 +08:00
zend_error ( E_NOTICE , " Trying to get property of non-object " ) ;
1999-04-08 02:10:10 +08:00
2002-02-07 22:08:43 +08:00
if ( type = = BP_VAR_R | | type = = BP_VAR_IS ) {
* retval = EG ( uninitialized_zval_ptr ) ;
} else {
* retval = EG ( error_zval_ptr ) ;
}
2001-05-03 03:51:33 +08:00
} else {
2002-02-07 22:08:43 +08:00
zval * offset ;
zval tmp ;
offset = get_zval_ptr ( op2 , Ts , & EG ( free_op2 ) , BP_VAR_R ) ;
switch ( op2 - > op_type ) {
case IS_CONST :
/* already a constant string */
break ;
case IS_VAR :
tmp = * offset ;
zval_copy_ctor ( & tmp ) ;
convert_to_string ( & tmp ) ;
offset = & tmp ;
break ;
case IS_TMP_VAR :
convert_to_string ( offset ) ;
break ;
}
/* here we are sure we are dealing with an object */
2003-02-05 22:27:30 +08:00
* retval = Z_OBJ_HT_P ( container ) - > read_property ( container , offset TSRMLS_CC ) ;
2002-02-07 22:08:43 +08:00
if ( offset = = & tmp ) {
zval_dtor ( offset ) ;
}
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
2001-05-03 03:51:33 +08:00
}
2002-02-07 22:08:43 +08:00
SELECTIVE_PZVAL_LOCK ( * retval , result ) ;
return ;
1999-04-08 02:10:10 +08:00
}
2002-03-10 21:42:37 +08:00
static void zend_pre_incdec_property ( znode * result , znode * op1 , znode * op2 , temp_variable * Ts , int ( * incdec_op ) ( zval * ) TSRMLS_DC )
{
2002-10-17 03:16:58 +08:00
zval * * object_ptr = get_obj_zval_ptr_ptr ( op1 , Ts , BP_VAR_W TSRMLS_CC ) ;
2002-03-10 21:42:37 +08:00
zval * object ;
zval * property = get_zval_ptr ( op2 , Ts , & EG ( free_op2 ) , BP_VAR_R ) ;
2002-10-24 04:26:28 +08:00
zval * * retval = & T ( result - > u . var ) . var . ptr ;
2002-09-04 17:07:58 +08:00
int have_get_ptr = 0 ;
2002-03-10 21:42:37 +08:00
2002-10-17 02:06:36 +08:00
make_real_object ( object_ptr TSRMLS_CC ) ; /* this should modify object only if it's empty */
2002-03-10 21:42:37 +08:00
object = * object_ptr ;
if ( object - > type ! = IS_OBJECT ) {
zend_error ( E_WARNING , " Attempt to increment/decrement property of non-object " ) ;
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
* retval = EG ( uninitialized_zval_ptr ) ;
SELECTIVE_PZVAL_LOCK ( * retval , result ) ;
return ;
}
/* here we are sure we are dealing with an object */
2002-09-15 15:45:26 +08:00
if ( Z_OBJ_HT_P ( object ) - > get_property_zval_ptr ) {
2002-03-10 21:42:37 +08:00
zval * * zptr = Z_OBJ_HT_P ( object ) - > get_property_zval_ptr ( object , property TSRMLS_CC ) ;
2002-09-15 15:45:26 +08:00
if ( zptr ! = NULL ) { /* NULL means no success in getting PTR */
2002-09-04 17:07:58 +08:00
SEPARATE_ZVAL_IF_NOT_REF ( zptr ) ;
2002-03-10 21:42:37 +08:00
2002-09-04 17:07:58 +08:00
have_get_ptr = 1 ;
incdec_op ( * zptr ) ;
* retval = * zptr ;
SELECTIVE_PZVAL_LOCK ( * retval , result ) ;
}
}
2002-09-15 15:45:26 +08:00
if ( ! have_get_ptr ) {
2003-02-05 22:27:30 +08:00
zval * z = Z_OBJ_HT_P ( object ) - > read_property ( object , property TSRMLS_CC ) ;
2002-03-10 21:42:37 +08:00
SEPARATE_ZVAL_IF_NOT_REF ( & z ) ;
incdec_op ( z ) ;
Z_OBJ_HT_P ( object ) - > write_property ( object , property , z TSRMLS_CC ) ;
2002-09-15 15:45:26 +08:00
if ( z - > refcount < = 1 ) {
2002-03-10 21:42:37 +08:00
zval_dtor ( z ) ;
}
}
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
}
static void zend_post_incdec_property ( znode * result , znode * op1 , znode * op2 , temp_variable * Ts , int ( * incdec_op ) ( zval * ) TSRMLS_DC )
{
2002-10-17 03:16:58 +08:00
zval * * object_ptr = get_obj_zval_ptr_ptr ( op1 , Ts , BP_VAR_W TSRMLS_CC ) ;
2002-03-10 21:42:37 +08:00
zval * object ;
zval * property = get_zval_ptr ( op2 , Ts , & EG ( free_op2 ) , BP_VAR_R ) ;
2002-10-24 04:26:28 +08:00
zval * retval = & T ( result - > u . var ) . tmp_var ;
2002-09-04 17:07:58 +08:00
int have_get_ptr = 0 ;
2002-03-10 21:42:37 +08:00
2002-10-17 02:06:36 +08:00
make_real_object ( object_ptr TSRMLS_CC ) ; /* this should modify object only if it's empty */
2002-03-10 21:42:37 +08:00
object = * object_ptr ;
if ( object - > type ! = IS_OBJECT ) {
zend_error ( E_WARNING , " Attempt to increment/decrement property of non-object " ) ;
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
* retval = * EG ( uninitialized_zval_ptr ) ;
return ;
}
/* here we are sure we are dealing with an object */
2002-09-15 15:45:26 +08:00
if ( Z_OBJ_HT_P ( object ) - > get_property_zval_ptr ) {
2002-03-10 21:42:37 +08:00
zval * * zptr = Z_OBJ_HT_P ( object ) - > get_property_zval_ptr ( object , property TSRMLS_CC ) ;
2002-09-15 15:45:26 +08:00
if ( zptr ! = NULL ) { /* NULL means no success in getting PTR */
2002-09-04 17:07:58 +08:00
have_get_ptr = 1 ;
SEPARATE_ZVAL_IF_NOT_REF ( zptr ) ;
* retval = * * zptr ;
zendi_zval_copy_ctor ( * retval ) ;
incdec_op ( * zptr ) ;
2002-03-10 21:42:37 +08:00
2002-09-04 17:07:58 +08:00
}
}
2002-03-10 21:42:37 +08:00
2002-09-15 15:45:26 +08:00
if ( ! have_get_ptr ) {
2003-02-05 22:27:30 +08:00
zval * z = Z_OBJ_HT_P ( object ) - > read_property ( object , property TSRMLS_CC ) ;
2002-03-10 21:42:37 +08:00
SEPARATE_ZVAL_IF_NOT_REF ( & z ) ;
* retval = * z ;
zendi_zval_copy_ctor ( * retval ) ;
incdec_op ( z ) ;
Z_OBJ_HT_P ( object ) - > write_property ( object , property , z TSRMLS_CC ) ;
2002-09-15 15:45:26 +08:00
if ( z - > refcount < = 1 ) {
2002-03-10 21:42:37 +08:00
zval_dtor ( z ) ;
}
}
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
}
1999-04-08 02:10:10 +08:00
2000-02-10 05:48:16 +08:00
# if ZEND_INTENSIVE_DEBUGGING
# define CHECK_SYMBOL_TABLES() \
2001-07-31 12:53:54 +08:00
zend_hash_apply ( & EG ( symbol_table ) , ( apply_func_t ) zend_check_symbol TSRMLS_CC ) ; \
2000-02-10 05:48:16 +08:00
if ( & EG ( symbol_table ) ! = EG ( active_symbol_table ) ) { \
2001-07-31 12:53:54 +08:00
zend_hash_apply ( EG ( active_symbol_table ) , ( apply_func_t ) zend_check_symbol TSRMLS_CC ) ; \
2000-02-10 05:48:16 +08:00
}
2001-07-31 12:53:54 +08:00
static int zend_check_symbol ( zval * * pz TSRMLS_DC )
2000-02-10 05:48:16 +08:00
{
2001-08-06 10:52:03 +08:00
if ( Z_TYPE_PP ( pz ) > 9 ) {
2000-02-10 05:48:16 +08:00
fprintf ( stderr , " Warning! %x has invalid type! \n " , * pz ) ;
2001-08-06 10:52:03 +08:00
} else if ( Z_TYPE_PP ( pz ) = = IS_ARRAY ) {
zend_hash_apply ( Z_ARRVAL_PP ( pz ) , ( apply_func_t ) zend_check_symbol TSRMLS_CC ) ;
} else if ( Z_TYPE_PP ( pz ) = = IS_OBJECT ) {
2002-02-07 22:08:43 +08:00
/* OBJ-TBI - doesn't support new object model! */
2001-08-06 10:52:03 +08:00
zend_hash_apply ( Z_OBJPROP_PP ( pz ) , ( apply_func_t ) zend_check_symbol TSRMLS_CC ) ;
2000-02-10 05:48:16 +08:00
}
return 0 ;
}
# else
# define CHECK_SYMBOL_TABLES()
# endif
# define NEXT_OPCODE() \
CHECK_SYMBOL_TABLES ( ) \
2001-10-01 01:29:55 +08:00
EX ( opline ) + + ; \
2002-10-19 05:19:27 +08:00
return 0 ; /* CHECK_ME */
2000-01-29 08:33:07 +08:00
2001-10-01 01:29:55 +08:00
# define RETURN_FROM_EXECUTE_LOOP(execute_data) \
free_alloca ( EX ( Ts ) ) ; \
EG ( in_execution ) = EX ( original_in_execution ) ; \
2002-05-03 01:20:48 +08:00
EG ( current_execute_data ) = EX ( prev_execute_data ) ; \
2002-10-19 05:19:27 +08:00
return 1 ; /* CHECK_ME */
opcode_handler_t zend_opcode_handlers [ 512 ] ;
2001-08-30 23:26:30 +08:00
2003-01-12 00:12:44 +08:00
ZEND_API void execute_internal ( zend_execute_data * execute_data_ptr , int return_value_used TSRMLS_DC )
{
( ( zend_internal_function * ) execute_data_ptr - > function_state . function ) - > handler ( execute_data_ptr - > opline - > extended_value , ( * ( temp_variable * ) ( ( char * ) execute_data_ptr - > Ts + execute_data_ptr - > opline - > result . u . var ) ) . var . ptr , execute_data_ptr - > object , return_value_used TSRMLS_CC ) ;
}
2001-10-01 01:29:55 +08:00
ZEND_API void execute ( zend_op_array * op_array TSRMLS_DC )
{
zend_execute_data execute_data ;
/* Initialize execute_data */
EX ( fbc ) = NULL ;
2002-05-03 01:20:48 +08:00
EX ( object ) = NULL ;
2001-10-01 01:29:55 +08:00
EX ( Ts ) = ( temp_variable * ) do_alloca ( sizeof ( temp_variable ) * op_array - > T ) ;
2002-07-26 18:38:25 +08:00
EX ( op_array ) = op_array ;
2002-05-03 01:20:48 +08:00
EX ( original_in_execution ) = EG ( in_execution ) ;
EX ( prev_execute_data ) = EG ( current_execute_data ) ;
EG ( current_execute_data ) = & execute_data ;
1999-04-08 02:10:10 +08:00
2000-02-04 22:45:58 +08:00
EG ( in_execution ) = 1 ;
2001-07-15 22:08:58 +08:00
if ( op_array - > start_op ) {
2001-10-01 01:29:55 +08:00
EX ( opline ) = op_array - > start_op ;
2001-07-15 22:08:58 +08:00
} else {
2001-10-01 01:29:55 +08:00
EX ( opline ) = op_array - > opcodes ;
1999-04-08 02:10:10 +08:00
}
2002-03-15 23:09:46 +08:00
if ( op_array - > uses_this & & EG ( This ) ) {
EG ( This ) - > refcount + + ; /* For $this pointer */
if ( zend_hash_add ( EG ( active_symbol_table ) , " this " , sizeof ( " this " ) , & EG ( This ) , sizeof ( zval * ) , NULL ) = = FAILURE ) {
EG ( This ) - > refcount - - ;
}
}
2001-10-01 01:29:55 +08:00
EG ( opline_ptr ) = & EX ( opline ) ;
1999-04-08 02:10:10 +08:00
2001-10-01 01:29:55 +08:00
EX ( function_state ) . function = ( zend_function * ) op_array ;
EG ( function_state_ptr ) = & EX ( function_state ) ;
1999-04-08 02:10:10 +08:00
# if ZEND_DEBUG
/* function_state.function_symbol_table is saved as-is to a stack,
* which is an intentional UMR . Shut it up if we ' re in DEBUG .
*/
2001-10-01 01:29:55 +08:00
EX ( function_state ) . function_symbol_table = NULL ;
1999-04-08 02:10:10 +08:00
# endif
2003-02-19 01:18:28 +08:00
if ( EG ( active_namespace ) ! = op_array - > ns ) {
zend_switch_namespace ( op_array - > ns TSRMLS_CC ) ;
2003-02-16 19:12:43 +08:00
}
2000-01-29 06:23:28 +08:00
while ( 1 ) {
2000-06-16 22:27:28 +08:00
# ifdef ZEND_WIN32
if ( EG ( timed_out ) ) {
zend_timeout ( 0 ) ;
}
# endif
2001-06-22 06:30:23 +08:00
2001-07-27 18:10:39 +08:00
zend_clean_garbage ( TSRMLS_C ) ;
2002-10-19 17:45:51 +08:00
if ( EX ( opline ) - > handler ( & execute_data , op_array TSRMLS_CC ) ) {
2002-10-19 05:19:27 +08:00
return ;
}
}
zend_error ( E_ERROR , " Arrived at end of main loop which shouldn't happen " ) ;
}
2001-06-22 06:30:23 +08:00
2002-10-19 05:19:27 +08:00
/* CHECK_ME */
# undef EX
# define EX(element) execute_data->element
2000-08-04 16:11:54 +08:00
2002-10-19 05:19:27 +08:00
int zend_add_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
add_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2002-03-10 21:42:37 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_sub_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
sub_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2002-03-10 21:42:37 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_mul_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
mul_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2002-03-10 21:42:37 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_div_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
div_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
1999-04-08 02:10:10 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_mod_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
mod_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
1999-04-08 02:10:10 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_sl_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
shift_left_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2000-02-17 00:49:44 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_sr_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
shift_right_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
1999-04-08 02:10:10 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_concat_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
concat_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2002-06-12 01:33:53 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_is_identical_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
is_identical_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2002-03-03 04:38:52 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_is_not_identical_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
is_not_identical_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2002-03-03 04:38:52 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_is_equal_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
is_equal_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2002-03-03 04:38:52 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_is_not_equal_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
is_not_equal_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2002-03-07 01:08:26 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_is_smaller_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
is_smaller_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2002-03-07 01:08:26 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_is_smaller_or_equal_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
is_smaller_or_equal_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2002-03-03 04:38:52 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_bw_or_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
bitwise_or_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2001-12-13 01:38:37 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_bw_and_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
bitwise_and_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2002-01-23 02:02:52 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_bw_xor_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
bitwise_xor_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2001-11-05 03:30:49 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_bool_xor_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
boolean_xor_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2001-11-05 03:30:49 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_bw_not_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
bitwise_not_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
NEXT_OPCODE ( ) ;
}
2002-10-15 04:13:03 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_bool_not_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
boolean_not_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
NEXT_OPCODE ( ) ;
}
2002-01-04 14:44:19 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
inline int zend_binary_assign_op_helper ( void * binary_op_arg , ZEND_OPCODE_HANDLER_ARGS )
{
zval * * var_ptr = get_zval_ptr_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , BP_VAR_RW ) ;
int ( * binary_op ) ( zval * result , zval * op1 , zval * op2 TSRMLS_DC ) = binary_op_arg ;
2002-01-04 14:44:19 +08:00
2002-10-19 05:19:27 +08:00
if ( ! var_ptr ) {
zend_error ( E_ERROR , " Cannot use assign-op operators with overloaded objects nor string offsets " ) ;
}
2002-01-04 14:44:19 +08:00
2002-10-19 05:19:27 +08:00
if ( * var_ptr = = EG ( error_zval_ptr ) ) {
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr = & EG ( uninitialized_zval_ptr ) ;
SELECTIVE_PZVAL_LOCK ( * EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr , & EX ( opline ) - > result ) ;
AI_USE_PTR ( EX_T ( EX ( opline ) - > result . u . var ) . var ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
SEPARATE_ZVAL_IF_NOT_REF ( var_ptr ) ;
2002-02-07 22:08:43 +08:00
2002-10-19 05:19:27 +08:00
binary_op ( * var_ptr , * var_ptr , get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr = var_ptr ;
2002-10-19 05:19:27 +08:00
SELECTIVE_PZVAL_LOCK ( * var_ptr , & EX ( opline ) - > result ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
2002-10-24 04:26:28 +08:00
AI_USE_PTR ( EX_T ( EX ( opline ) - > result . u . var ) . var ) ;
2002-02-07 22:08:43 +08:00
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2002-01-04 16:05:21 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_add_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_binary_assign_op_helper ( add_function , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2002-01-04 16:05:21 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_sub_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_binary_assign_op_helper ( sub_function , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2002-01-04 16:05:21 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_mul_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_binary_assign_op_helper ( mul_function , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2002-02-07 22:08:43 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_div_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_binary_assign_op_helper ( div_function , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2002-01-04 16:05:21 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_mod_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_binary_assign_op_helper ( mod_function , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2002-01-04 16:05:21 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_sl_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_binary_assign_op_helper ( shift_left_function , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2002-01-04 16:05:21 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_sr_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_binary_assign_op_helper ( shift_right_function , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2002-01-04 16:05:21 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_concat_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_binary_assign_op_helper ( concat_function , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2002-01-05 23:18:30 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_bw_or_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_binary_assign_op_helper ( bitwise_or_function , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2002-01-04 16:05:21 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_bw_and_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_binary_assign_op_helper ( bitwise_and_function , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2002-01-04 16:05:21 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_bw_xor_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_binary_assign_op_helper ( bitwise_xor_function , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2002-01-04 16:05:21 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_add_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-01-27 23:13:01 +08:00
zend_op * op_data = EX ( opline ) + 1 ;
zend_assign_to_object_op ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , & op_data - > op1 , EX ( Ts ) , add_function TSRMLS_CC ) ;
/* assign_obj has two opcodes! */
EX ( opline ) + + ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2002-01-04 16:05:21 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_sub_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-01-27 23:13:01 +08:00
zend_op * op_data = EX ( opline ) + 1 ;
zend_assign_to_object_op ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , & op_data - > op1 , EX ( Ts ) , sub_function TSRMLS_CC ) ;
/* assign_obj has two opcodes! */
EX ( opline ) + + ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2002-01-04 16:05:21 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_mul_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-01-27 23:13:01 +08:00
zend_op * op_data = EX ( opline ) + 1 ;
zend_assign_to_object_op ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , & op_data - > op1 , EX ( Ts ) , mul_function TSRMLS_CC ) ;
/* assign_obj has two opcodes! */
EX ( opline ) + + ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2002-01-04 17:21:16 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_div_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-01-27 23:13:01 +08:00
zend_op * op_data = EX ( opline ) + 1 ;
zend_assign_to_object_op ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , & op_data - > op1 , EX ( Ts ) , div_function TSRMLS_CC ) ;
/* assign_obj has two opcodes! */
EX ( opline ) + + ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2002-01-04 17:21:16 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_mod_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-01-27 23:13:01 +08:00
zend_op * op_data = EX ( opline ) + 1 ;
zend_assign_to_object_op ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , & op_data - > op1 , EX ( Ts ) , mod_function TSRMLS_CC ) ;
/* assign_obj has two opcodes! */
EX ( opline ) + + ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_sl_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-01-27 23:13:01 +08:00
zend_op * op_data = EX ( opline ) + 1 ;
zend_assign_to_object_op ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , & op_data - > op1 , EX ( Ts ) , shift_left_function TSRMLS_CC ) ;
/* assign_obj has two opcodes! */
EX ( opline ) + + ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_sr_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-01-27 23:13:01 +08:00
zend_op * op_data = EX ( opline ) + 1 ;
zend_assign_to_object_op ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , & op_data - > op1 , EX ( Ts ) , shift_right_function TSRMLS_CC ) ;
/* assign_obj has two opcodes! */
EX ( opline ) + + ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_concat_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-01-27 23:13:01 +08:00
zend_op * op_data = EX ( opline ) + 1 ;
zend_assign_to_object_op ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , & op_data - > op1 , EX ( Ts ) , concat_function TSRMLS_CC ) ;
/* assign_obj has two opcodes! */
EX ( opline ) + + ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_bw_or_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-01-27 23:13:01 +08:00
zend_op * op_data = EX ( opline ) + 1 ;
zend_assign_to_object_op ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , & op_data - > op1 , EX ( Ts ) , bitwise_or_function TSRMLS_CC ) ;
/* assign_obj has two opcodes! */
EX ( opline ) + + ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_bw_and_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-01-27 23:13:01 +08:00
zend_op * op_data = EX ( opline ) + 1 ;
zend_assign_to_object_op ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , & op_data - > op1 , EX ( Ts ) , bitwise_and_function TSRMLS_CC ) ;
/* assign_obj has two opcodes! */
EX ( opline ) + + ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_bw_xor_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-01-27 23:13:01 +08:00
zend_op * op_data = EX ( opline ) + 1 ;
zend_assign_to_object_op ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , & op_data - > op1 , EX ( Ts ) , bitwise_xor_function TSRMLS_CC ) ;
/* assign_obj has two opcodes! */
EX ( opline ) + + ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_pre_inc_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_pre_incdec_property ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , increment_function TSRMLS_CC ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_pre_dec_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_pre_incdec_property ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , decrement_function TSRMLS_CC ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_post_inc_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_post_incdec_property ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , increment_function TSRMLS_CC ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_post_dec_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_post_incdec_property ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , decrement_function TSRMLS_CC ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
inline int zend_incdec_op_helper ( void * incdec_op_arg , ZEND_OPCODE_HANDLER_ARGS )
{
zval * * var_ptr = get_zval_ptr_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , BP_VAR_RW ) ;
int ( * incdec_op ) ( zval * op1 ) = incdec_op_arg ;
if ( ! var_ptr ) {
zend_error ( E_ERROR , " Cannot increment/decrement overloaded objects nor string offsets " ) ;
}
if ( * var_ptr = = EG ( error_zval_ptr ) ) {
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr = & EG ( uninitialized_zval_ptr ) ;
SELECTIVE_PZVAL_LOCK ( * EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr , & EX ( opline ) - > result ) ;
AI_USE_PTR ( EX_T ( EX ( opline ) - > result . u . var ) . var ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
switch ( EX ( opline ) - > opcode ) {
case ZEND_POST_INC :
case ZEND_POST_DEC :
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var = * * var_ptr ;
zendi_zval_copy_ctor ( EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ) ;
2002-10-19 05:19:27 +08:00
break ;
}
SEPARATE_ZVAL_IF_NOT_REF ( var_ptr ) ;
incdec_op ( * var_ptr ) ;
switch ( EX ( opline ) - > opcode ) {
case ZEND_PRE_INC :
case ZEND_PRE_DEC :
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr = var_ptr ;
2002-10-19 05:19:27 +08:00
SELECTIVE_PZVAL_LOCK ( * var_ptr , & EX ( opline ) - > result ) ;
2002-10-24 04:26:28 +08:00
AI_USE_PTR ( EX_T ( EX ( opline ) - > result . u . var ) . var ) ;
2002-10-19 05:19:27 +08:00
break ;
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_pre_inc_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_incdec_op_helper ( increment_function , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_pre_dec_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_incdec_op_helper ( decrement_function , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_post_inc_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_incdec_op_helper ( increment_function , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_post_dec_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_incdec_op_helper ( decrement_function , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_print_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_print_variable ( get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ) ;
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . value . lval = 1 ;
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . type = IS_LONG ;
2002-10-19 05:19:27 +08:00
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_echo_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_print_variable ( get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_r_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_fetch_var_address ( EX ( opline ) , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
2002-10-24 04:26:28 +08:00
AI_USE_PTR ( EX_T ( EX ( opline ) - > result . u . var ) . var ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_w_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_fetch_var_address ( EX ( opline ) , EX ( Ts ) , BP_VAR_W TSRMLS_CC ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_rw_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_fetch_var_address ( EX ( opline ) , EX ( Ts ) , BP_VAR_RW TSRMLS_CC ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_func_arg_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
if ( ARG_SHOULD_BE_SENT_BY_REF ( EX ( opline ) - > extended_value , EX ( fbc ) , EX ( fbc ) - > common . arg_types ) ) {
/* Behave like FETCH_W */
zend_fetch_var_address ( EX ( opline ) , EX ( Ts ) , BP_VAR_W TSRMLS_CC ) ;
} else {
/* Behave like FETCH_R */
zend_fetch_var_address ( EX ( opline ) , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
2002-10-24 04:26:28 +08:00
AI_USE_PTR ( EX_T ( EX ( opline ) - > result . u . var ) . var ) ;
2002-10-19 05:19:27 +08:00
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_unset_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_fetch_var_address ( EX ( opline ) , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
2002-10-24 04:26:28 +08:00
PZVAL_UNLOCK ( * EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr ) ;
if ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr ! = & EG ( uninitialized_zval_ptr ) ) {
SEPARATE_ZVAL_IF_NOT_REF ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr ) ;
2002-10-19 05:19:27 +08:00
}
2002-10-24 04:26:28 +08:00
PZVAL_LOCK ( * EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_is_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_fetch_var_address ( EX ( opline ) , EX ( Ts ) , BP_VAR_IS TSRMLS_CC ) ;
2002-10-24 04:26:28 +08:00
AI_USE_PTR ( EX_T ( EX ( opline ) - > result . u . var ) . var ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_dim_r_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
if ( EX ( opline ) - > extended_value = = ZEND_FETCH_ADD_LOCK ) {
2002-10-24 04:26:28 +08:00
PZVAL_LOCK ( * EX_T ( EX ( opline ) - > op1 . u . var ) . var . ptr_ptr ) ;
2002-10-19 05:19:27 +08:00
}
zend_fetch_dimension_address ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
2002-10-24 04:26:28 +08:00
AI_USE_PTR ( EX_T ( EX ( opline ) - > result . u . var ) . var ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_dim_w_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_fetch_dimension_address ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , BP_VAR_W TSRMLS_CC ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_dim_rw_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_fetch_dimension_address ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , BP_VAR_RW TSRMLS_CC ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_dim_is_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_fetch_dimension_address ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , BP_VAR_IS TSRMLS_CC ) ;
2002-10-24 04:26:28 +08:00
AI_USE_PTR ( EX_T ( EX ( opline ) - > result . u . var ) . var ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_dim_func_arg_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
if ( ARG_SHOULD_BE_SENT_BY_REF ( EX ( opline ) - > extended_value , EX ( fbc ) , EX ( fbc ) - > common . arg_types ) ) {
/* Behave like FETCH_DIM_W */
zend_fetch_dimension_address ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , BP_VAR_W TSRMLS_CC ) ;
} else {
/* Behave like FETCH_DIM_R, except for locking used for list() */
zend_fetch_dimension_address ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
2002-10-24 04:26:28 +08:00
AI_USE_PTR ( EX_T ( EX ( opline ) - > result . u . var ) . var ) ;
2002-10-19 05:19:27 +08:00
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_dim_unset_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
/* Not needed in DIM_UNSET
if ( EX ( opline ) - > extended_value = = ZEND_FETCH_ADD_LOCK ) {
2002-10-24 04:26:28 +08:00
PZVAL_LOCK ( * EX_T ( EX ( opline ) - > op1 . u . var ) . var . ptr_ptr ) ;
2002-10-19 05:19:27 +08:00
}
*/
zend_fetch_dimension_address ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
2002-10-24 04:26:28 +08:00
PZVAL_UNLOCK ( * EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr ) ;
if ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr ! = & EG ( uninitialized_zval_ptr ) ) {
SEPARATE_ZVAL_IF_NOT_REF ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr ) ;
2002-10-19 05:19:27 +08:00
}
2002-10-24 04:26:28 +08:00
PZVAL_LOCK ( * EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_obj_r_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_fetch_property_address_read ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
2002-10-24 04:26:28 +08:00
AI_USE_PTR ( EX_T ( EX ( opline ) - > result . u . var ) . var ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_obj_w_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_fetch_property_address ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , BP_VAR_W TSRMLS_CC ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_obj_rw_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_fetch_property_address ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , BP_VAR_RW TSRMLS_CC ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_obj_is_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_fetch_property_address_read ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , BP_VAR_IS TSRMLS_CC ) ;
2002-10-24 04:26:28 +08:00
AI_USE_PTR ( EX_T ( EX ( opline ) - > result . u . var ) . var ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_obj_func_arg_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
if ( ARG_SHOULD_BE_SENT_BY_REF ( EX ( opline ) - > extended_value , EX ( fbc ) , EX ( fbc ) - > common . arg_types ) ) {
/* Behave like FETCH_OBJ_W */
zend_fetch_property_address ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , BP_VAR_W TSRMLS_CC ) ;
} else {
zend_fetch_property_address_read ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
2002-10-24 04:26:28 +08:00
AI_USE_PTR ( EX_T ( EX ( opline ) - > result . u . var ) . var ) ;
2002-10-19 05:19:27 +08:00
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_obj_unset_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_fetch_property_address ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
2002-10-24 04:26:28 +08:00
PZVAL_UNLOCK ( * EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr ) ;
if ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr ! = & EG ( uninitialized_zval_ptr ) ) {
SEPARATE_ZVAL_IF_NOT_REF ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr ) ;
2002-10-19 05:19:27 +08:00
}
2002-10-24 04:26:28 +08:00
PZVAL_LOCK ( * EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_dim_tmp_var_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_fetch_dimension_address_from_tmp_var ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , EX ( Ts ) TSRMLS_CC ) ;
2002-10-24 04:26:28 +08:00
AI_USE_PTR ( EX_T ( EX ( opline ) - > result . u . var ) . var ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_make_var_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * value , * value2 ;
value = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2002-11-30 19:20:25 +08:00
switch ( EX ( opline ) - > op1 . op_type ) {
2002-10-19 05:19:27 +08:00
case IS_TMP_VAR :
value2 = value ;
ALLOC_ZVAL ( value ) ;
* value = * value2 ;
value - > is_ref = 0 ;
value - > refcount = 0 ; /* lock will increase this */
break ;
case IS_CONST :
value2 = value ;
ALLOC_ZVAL ( value ) ;
* value = * value2 ;
zval_copy_ctor ( value ) ;
value - > is_ref = 0 ;
value - > refcount = 0 ; /* lock will increase this */
break ;
}
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr = value ;
PZVAL_LOCK ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-01-27 23:13:01 +08:00
zend_op * op_data = EX ( opline ) + 1 ;
zend_assign_to_object ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , & op_data - > op1 , EX ( Ts ) TSRMLS_CC ) ;
/* assign_obj has two opcodes! */
EX ( opline ) + + ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * value ;
value = get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
zend_assign_to_variable ( & EX ( opline ) - > result , & EX ( opline ) - > op1 , & EX ( opline ) - > op2 , value , ( EG ( free_op2 ) ? IS_TMP_VAR : EX ( opline ) - > op2 . op_type ) , EX ( Ts ) TSRMLS_CC ) ;
/* zend_assign_to_variable() always takes care of op2, never free it! */
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_assign_ref_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * * value_ptr_ptr = get_zval_ptr_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , BP_VAR_W ) ;
zend_assign_to_variable_reference ( & EX ( opline ) - > result , get_zval_ptr_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , BP_VAR_W ) , value_ptr_ptr , EX ( Ts ) TSRMLS_CC ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_jmp_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
# if DEBUG_ZEND>=2
printf ( " Jumping to %d \n " , EX ( opline ) - > op1 . u . opline_num ) ;
# endif
2002-10-25 02:04:12 +08:00
EX ( opline ) = EX ( opline ) - > op1 . u . jmp_addr ;
2002-10-19 05:19:27 +08:00
return 0 ; /* CHECK_ME */
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_jmpz_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
znode * op1 = & EX ( opline ) - > op1 ;
if ( ! i_zend_is_true ( get_zval_ptr ( op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ) ) {
# if DEBUG_ZEND>=2
printf ( " Conditional jmp to %d \n " , EX ( opline ) - > op2 . u . opline_num ) ;
# endif
2002-10-25 02:04:12 +08:00
EX ( opline ) = EX ( opline ) - > op2 . u . jmp_addr ;
2002-10-19 05:19:27 +08:00
FREE_OP ( EX ( Ts ) , op1 , EG ( free_op1 ) ) ;
return 0 ; /* CHECK_ME */
}
FREE_OP ( EX ( Ts ) , op1 , EG ( free_op1 ) ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_jmpnz_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
znode * op1 = & EX ( opline ) - > op1 ;
if ( zend_is_true ( get_zval_ptr ( op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ) ) {
# if DEBUG_ZEND>=2
printf ( " Conditional jmp to %d \n " , EX ( opline ) - > op2 . u . opline_num ) ;
# endif
2002-10-25 02:04:12 +08:00
EX ( opline ) = EX ( opline ) - > op2 . u . jmp_addr ;
2002-10-19 05:19:27 +08:00
FREE_OP ( EX ( Ts ) , op1 , EG ( free_op1 ) ) ;
return 0 ; /* CHECK_ME */
}
FREE_OP ( EX ( Ts ) , op1 , EG ( free_op1 ) ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_jmpznz_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
znode * res = & EX ( opline ) - > op1 ;
if ( zend_is_true ( get_zval_ptr ( res , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ) ) {
# if DEBUG_ZEND>=2
printf ( " Conditional jmp on true to %d \n " , EX ( opline ) - > extended_value ) ;
# endif
EX ( opline ) = & op_array - > opcodes [ EX ( opline ) - > extended_value ] ;
} else {
# if DEBUG_ZEND>=2
printf ( " Conditional jmp on false to %d \n " , EX ( opline ) - > op2 . u . opline_num ) ;
# endif
EX ( opline ) = & op_array - > opcodes [ EX ( opline ) - > op2 . u . opline_num ] ;
}
FREE_OP ( EX ( Ts ) , res , EG ( free_op1 ) ) ;
return 0 ; /* CHECK_ME */
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_jmpz_ex_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_op * original_opline = EX ( opline ) ;
int retval = zend_is_true ( get_zval_ptr ( & original_opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ) ;
FREE_OP ( EX ( Ts ) , & original_opline - > op1 , EG ( free_op1 ) ) ;
2002-10-24 04:26:28 +08:00
EX_T ( original_opline - > result . u . var ) . tmp_var . value . lval = retval ;
EX_T ( original_opline - > result . u . var ) . tmp_var . type = IS_BOOL ;
2002-10-19 05:19:27 +08:00
if ( ! retval ) {
# if DEBUG_ZEND>=2
printf ( " Conditional jmp to %d \n " , EX ( opline ) - > op2 . u . opline_num ) ;
# endif
2002-10-25 02:24:55 +08:00
EX ( opline ) = EX ( opline ) - > op2 . u . jmp_addr ;
2002-10-19 05:19:27 +08:00
return 0 ; /* CHECK_ME */
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_jmpnz_ex_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_op * original_opline = EX ( opline ) ;
int retval = zend_is_true ( get_zval_ptr ( & original_opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ) ;
FREE_OP ( EX ( Ts ) , & original_opline - > op1 , EG ( free_op1 ) ) ;
2002-10-24 04:26:28 +08:00
EX_T ( original_opline - > result . u . var ) . tmp_var . value . lval = retval ;
EX_T ( original_opline - > result . u . var ) . tmp_var . type = IS_BOOL ;
2002-10-19 05:19:27 +08:00
if ( retval ) {
# if DEBUG_ZEND>=2
printf ( " Conditional jmp to %d \n " , EX ( opline ) - > op2 . u . opline_num ) ;
# endif
2002-10-25 02:24:55 +08:00
EX ( opline ) = EX ( opline ) - > op2 . u . jmp_addr ;
2002-10-19 05:19:27 +08:00
return 0 ; /* CHECK_ME */
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_free_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
zendi_zval_dtor ( EX_T ( EX ( opline ) - > op1 . u . var ) . tmp_var ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_init_string_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . value . str . val = emalloc ( 1 ) ;
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . value . str . val [ 0 ] = 0 ;
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . value . str . len = 0 ;
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . refcount = 1 ;
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . type = IS_STRING ;
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . is_ref = 0 ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_add_char_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
add_char_to_string ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_NA ) ,
& EX ( opline ) - > op2 . u . constant ) ;
/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_add_string_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
add_string_to_string ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_NA ) ,
& EX ( opline ) - > op2 . u . constant ) ;
/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_add_var_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * var = get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
zval var_copy ;
int use_copy ;
zend_make_printable_zval ( var , & var_copy , & use_copy ) ;
if ( use_copy ) {
var = & var_copy ;
}
2002-10-24 04:26:28 +08:00
add_string_to_string ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_NA ) ,
var ) ;
if ( use_copy ) {
zval_dtor ( var ) ;
}
/* original comment, possibly problematic:
* FREE_OP is missing intentionally here - we ' re always working on the same temporary variable
* ( Zeev ) : I don ' t think it ' s problematic , we only use variables
* which aren ' t affected by FREE_OP ( Ts , ) ' s anyway , unless they ' re
* string offsets or overloaded objects
*/
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2003-04-21 20:14:12 +08:00
static int zend_import_check_function ( HashTable * target_ht , zend_function * function , zend_hash_key * hash_key , void * param )
{
if ( zend_hash_quick_exists ( target_ht , hash_key - > arKey , hash_key - > nKeyLength , hash_key - > h ) ) {
zend_error ( E_ERROR , " Import: function %s() already exists in current scope " , function - > common . function_name ? function - > common . function_name : " main " ) ;
}
return 1 ; /* OK */
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_import_function_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_class_entry * ce ;
zend_function * function ;
2002-10-24 04:26:28 +08:00
ce = EX_T ( EX ( opline ) - > op1 . u . var ) . EA . class_entry ;
2002-10-19 05:19:27 +08:00
if ( EX ( opline ) - > op2 . op_type ! = IS_UNUSED ) {
char * function_name_strval ;
int function_name_strlen ;
function_name_strval = EX ( opline ) - > op2 . u . constant . value . str . val ;
function_name_strlen = EX ( opline ) - > op2 . u . constant . value . str . len ;
if ( zend_hash_find ( & ce - > function_table , function_name_strval , function_name_strlen + 1 , ( void * * ) & function ) = = FAILURE ) {
zend_error ( E_ERROR , " Import: function %s() not found " , function_name_strval ) ;
}
if ( zend_hash_add ( EG ( function_table ) , function_name_strval , function_name_strlen + 1 , function , sizeof ( zend_function ) , NULL ) = = FAILURE ) {
zend_error ( E_ERROR , " Import: function %s() already exists in current scope " , function_name_strval ) ;
}
function_add_ref ( function ) ;
} else {
2003-04-21 20:14:12 +08:00
zend_hash_merge_ex ( EG ( function_table ) , & ce - > function_table , ( copy_ctor_func_t ) function_add_ref , sizeof ( zend_function ) , ( merge_checker_func_t ) zend_import_check_function , NULL ) ;
2002-10-19 05:19:27 +08:00
}
NEXT_OPCODE ( ) ;
}
2003-04-21 20:14:12 +08:00
static int zend_import_check_class ( HashTable * target_ht , zend_class_entry * * ce , zend_hash_key * hash_key , void * param )
{
if ( zend_hash_quick_exists ( target_ht , hash_key - > arKey , hash_key - > nKeyLength , hash_key - > h ) ) {
zend_error ( E_ERROR , " Import: class '%s' already exists in current scope " , ( * ce ) - > name ) ;
}
return 1 ; /* OK */
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_import_class_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_class_entry * ce ;
zend_class_entry * * import_ce ;
2002-10-24 04:26:28 +08:00
ce = EX_T ( EX ( opline ) - > op1 . u . var ) . EA . class_entry ;
2002-10-19 05:19:27 +08:00
if ( EX ( opline ) - > op2 . op_type ! = IS_UNUSED ) {
char * class_name_strval ;
int class_name_strlen ;
class_name_strval = EX ( opline ) - > op2 . u . constant . value . str . val ;
class_name_strlen = EX ( opline ) - > op2 . u . constant . value . str . len ;
if ( zend_hash_find ( & ce - > class_table , class_name_strval , class_name_strlen + 1 , ( void * * ) & import_ce ) = = FAILURE ) {
zend_error ( E_ERROR , " Import: class %s not found " , class_name_strval ) ;
}
if ( zend_hash_add ( EG ( class_table ) , class_name_strval , class_name_strlen + 1 , import_ce , sizeof ( zend_class_entry * ) , NULL ) = = FAILURE ) {
zend_error ( E_ERROR , " Import: class %s already exists in current scope " , class_name_strval ) ;
}
zend_class_add_ref ( import_ce ) ;
} else {
2003-04-21 20:14:12 +08:00
zend_hash_merge_ex ( EG ( class_table ) , & ce - > class_table , ( copy_ctor_func_t ) zend_class_add_ref , sizeof ( zend_class_entry * ) , ( merge_checker_func_t ) zend_import_check_class , NULL ) ;
2002-10-19 05:19:27 +08:00
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_import_const_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_class_entry * ce ;
zval * * import_constant ;
zend_constant c ;
2002-10-24 04:26:28 +08:00
ce = EX_T ( EX ( opline ) - > op1 . u . var ) . EA . class_entry ;
2002-10-19 05:19:27 +08:00
if ( EX ( opline ) - > op2 . op_type ! = IS_UNUSED ) {
char * const_name_strval ;
int const_name_strlen ;
const_name_strval = EX ( opline ) - > op2 . u . constant . value . str . val ;
const_name_strlen = EX ( opline ) - > op2 . u . constant . value . str . len ;
if ( zend_hash_find ( & ce - > constants_table , const_name_strval , const_name_strlen + 1 , ( void * * ) & import_constant ) = = FAILURE ) {
zend_error ( E_ERROR , " Import: constant %s not found " , const_name_strval ) ;
}
c . value = * * import_constant ;
zval_copy_ctor ( & c . value ) ;
c . flags = CONST_CS ;
c . name = zend_strndup ( const_name_strval , const_name_strlen ) ;
c . name_len = const_name_strlen + 1 ;
if ( zend_register_constant ( & c TSRMLS_CC ) = = FAILURE ) {
zend_error ( E_ERROR , " Import: unable to register constant %s " , const_name_strval ) ;
}
} else {
HashPosition pos ;
char * key ;
uint key_length ;
int key_type ;
ulong dummy ;
zend_hash_internal_pointer_reset_ex ( & ce - > constants_table , & pos ) ;
while ( zend_hash_get_current_data_ex ( & ce - > constants_table , ( void * * ) & import_constant , & pos ) = = SUCCESS ) {
key_type = zend_hash_get_current_key_ex ( & ce - > constants_table , & key , & key_length , & dummy , 0 , & pos ) ;
c . value = * * import_constant ;
zval_copy_ctor ( & c . value ) ;
c . flags = CONST_CS ;
c . name = zend_strndup ( key , key_length - 1 ) ;
c . name_len = key_length ;
if ( zend_register_constant ( & c TSRMLS_CC ) = = FAILURE ) {
zend_error ( E_ERROR , " Import: unable to register constant %s " , key ) ;
}
zend_hash_move_forward_ex ( & ce - > constants_table , & pos ) ;
}
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_class_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_class_entry * * pce ;
2003-03-05 21:25:33 +08:00
zend_class_entry * ce = NULL ;
2002-10-19 05:19:27 +08:00
zend_bool is_const ;
2003-03-07 07:45:50 +08:00
char * class_name_strval = NULL ;
zend_uint class_name_strlen = 0 ;
2002-10-19 05:19:27 +08:00
zval * class_name ;
zval tmp ;
2003-02-16 19:12:43 +08:00
if ( EX ( opline ) - > op2 . op_type = = IS_UNUSED ) {
2002-10-19 05:19:27 +08:00
if ( EX ( opline ) - > extended_value = = ZEND_FETCH_CLASS_SELF ) {
if ( ! EG ( scope ) ) {
2003-02-10 17:45:27 +08:00
zend_error ( E_ERROR , " Cannot access self:: when no class scope is active " ) ;
2002-10-19 05:19:27 +08:00
}
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . EA . class_entry = EG ( scope ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
} else if ( EX ( opline ) - > extended_value = = ZEND_FETCH_CLASS_MAIN ) {
2003-02-16 19:12:43 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . EA . class_entry = EG ( global_namespace_ptr ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
} else if ( EX ( opline ) - > extended_value = = ZEND_FETCH_CLASS_PARENT ) {
if ( ! EG ( scope ) ) {
2003-02-10 17:45:27 +08:00
zend_error ( E_ERROR , " Cannot access parent:: when no class scope is active " ) ;
2002-10-19 05:19:27 +08:00
}
if ( ! EG ( scope ) - > parent ) {
2003-02-10 17:45:27 +08:00
zend_error ( E_ERROR , " Cannot access parent:: when current class scope has no parent " ) ;
2002-10-19 05:19:27 +08:00
}
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . EA . class_entry = EG ( scope ) - > parent ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
2003-02-16 19:12:43 +08:00
}
2002-10-19 05:19:27 +08:00
}
is_const = ( EX ( opline ) - > op2 . op_type = = IS_CONST ) ;
if ( is_const ) {
2003-03-07 07:45:50 +08:00
class_name_strval = EX ( opline ) - > op2 . u . constant . value . str . val ;
class_name_strlen = EX ( opline ) - > op2 . u . constant . value . str . len ;
2002-10-19 05:19:27 +08:00
} else {
class_name = get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
2003-03-05 21:25:33 +08:00
if ( class_name - > type = = IS_OBJECT ) {
ce = Z_OBJCE_P ( class_name ) ;
} else {
tmp = * class_name ;
zval_copy_ctor ( & tmp ) ;
convert_to_string ( & tmp ) ;
zend_str_tolower ( tmp . value . str . val , tmp . value . str . len ) ;
2002-10-19 05:19:27 +08:00
2003-03-05 21:25:33 +08:00
class_name_strval = tmp . value . str . val ;
class_name_strlen = tmp . value . str . len ;
}
2002-10-19 05:19:27 +08:00
}
2003-03-05 21:25:33 +08:00
if ( ! ce ) {
2003-05-05 03:11:48 +08:00
int retval ;
2003-03-05 21:25:33 +08:00
if ( EX ( opline ) - > op1 . op_type = = IS_UNUSED & & EX ( opline ) - > extended_value ! = ZEND_FETCH_CLASS_GLOBAL ) {
retval = zend_lookup_class ( class_name_strval , class_name_strlen , & pce TSRMLS_CC ) ;
if ( retval = = FAILURE ) {
/* try namespace */
2003-04-02 23:28:31 +08:00
if ( zend_hash_find ( & EG ( global_namespace_ptr ) - > class_table , class_name_strval , class_name_strlen + 1 , ( void * * ) & pce ) = = SUCCESS & & CLASS_IS_NAMESPACE ( ( * pce ) ) ) {
2003-03-05 21:25:33 +08:00
retval = SUCCESS ;
}
2003-02-16 19:12:43 +08:00
}
} else {
2003-03-05 21:25:33 +08:00
zend_namespace * ns ;
/* Looking for namespace */
if ( EX ( opline ) - > extended_value = = ZEND_FETCH_CLASS_GLOBAL ) {
ns = EG ( global_namespace_ptr ) ;
} else {
2003-04-02 23:28:31 +08:00
if ( zend_hash_find ( & EG ( global_namespace_ptr ) - > class_table , EX ( opline ) - > op1 . u . constant . value . str . val , EX ( opline ) - > op1 . u . constant . value . str . len + 1 , ( void * * ) & pce ) = = FAILURE | | ! CLASS_IS_NAMESPACE ( ( * pce ) ) ) {
2003-03-05 21:25:33 +08:00
zend_error ( E_ERROR , " Namespace '%s' not found " , EX ( opline ) - > op1 . u . constant . value . str . val ) ;
}
ns = * pce ;
2003-02-16 19:12:43 +08:00
}
2003-03-05 21:25:33 +08:00
retval = zend_hash_find ( & ns - > class_table , class_name_strval , class_name_strlen + 1 , ( void * * ) & pce ) ;
}
if ( retval = = SUCCESS ) {
ce = * pce ;
2003-02-16 19:12:43 +08:00
}
2002-10-19 05:19:27 +08:00
}
2003-05-05 03:11:48 +08:00
if ( ! ce ) {
2002-10-19 05:19:27 +08:00
zend_error ( E_ERROR , " Class '%s' not found " , class_name_strval ) ;
} else {
2003-03-05 21:25:33 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . EA . class_entry = ce ;
2002-10-19 05:19:27 +08:00
}
if ( ! is_const ) {
zval_dtor ( & tmp ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
}
NEXT_OPCODE ( ) ;
}
2002-12-07 01:09:44 +08:00
2002-12-08 05:37:09 +08:00
int zend_init_ctor_call_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_ptr_stack_n_push ( & EG ( arg_types_stack ) , 3 , EX ( fbc ) , EX ( object ) , EX ( calling_scope ) ) ;
if ( EX ( opline ) - > op1 . op_type = = IS_VAR ) {
SELECTIVE_PZVAL_LOCK ( * EX_T ( EX ( opline ) - > op1 . u . var ) . var . ptr_ptr , & EX ( opline ) - > op1 ) ;
}
/* We are not handling overloaded classes right now */
EX ( object ) = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
if ( ! PZVAL_IS_REF ( EX ( object ) ) ) {
EX ( object ) - > refcount + + ; /* For $this pointer */
} else {
zval * this_ptr ;
ALLOC_ZVAL ( this_ptr ) ;
* this_ptr = * EX ( object ) ;
INIT_PZVAL ( this_ptr ) ;
zval_copy_ctor ( this_ptr ) ;
EX ( object ) = this_ptr ;
}
EX ( fbc ) = EX ( fbc_constructor ) ;
if ( EX ( fbc ) - > type = = ZEND_USER_FUNCTION ) { /* HACK!! */
EX ( calling_scope ) = EX ( fbc ) - > common . scope ;
} else {
EX ( calling_scope ) = NULL ;
}
NEXT_OPCODE ( ) ;
}
2002-10-19 05:19:27 +08:00
int zend_init_method_call_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * function_name ;
char * function_name_strval ;
int function_name_strlen ;
zend_ptr_stack_n_push ( & EG ( arg_types_stack ) , 3 , EX ( fbc ) , EX ( object ) , EX ( calling_scope ) ) ;
function_name = get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
function_name_strval = function_name - > value . str . val ;
function_name_strlen = function_name - > value . str . len ;
EX ( calling_scope ) = EG ( scope ) ;
EX ( object ) = get_obj_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R TSRMLS_CC ) ;
if ( EX ( object ) & & EX ( object ) - > type = = IS_OBJECT ) {
2002-12-07 01:09:44 +08:00
/* First, locate the function. */
2002-10-19 05:19:27 +08:00
EX ( fbc ) = Z_OBJ_HT_P ( EX ( object ) ) - > get_method ( EX ( object ) , function_name_strval , function_name_strlen TSRMLS_CC ) ;
2002-11-24 04:44:12 +08:00
if ( ! EX ( fbc ) ) {
2002-12-07 01:09:44 +08:00
zend_error ( E_ERROR , " Call to undefined method %s::%s() " , Z_OBJ_CLASS_NAME_P ( EX ( object ) ) , function_name_strval ) ;
}
2002-10-19 05:19:27 +08:00
} else {
2002-11-24 04:44:12 +08:00
zend_error ( E_ERROR , " Call to a member function %s() on a non-object " , function_name_strval ) ;
2002-10-19 05:19:27 +08:00
}
2002-12-07 01:09:44 +08:00
if ( EX ( fbc ) - > common . fn_flags & ZEND_ACC_STATIC ) {
2002-11-06 03:37:31 +08:00
EX ( object ) = NULL ;
2002-10-19 05:19:27 +08:00
} else {
2002-11-06 03:37:31 +08:00
if ( ! PZVAL_IS_REF ( EX ( object ) ) ) {
EX ( object ) - > refcount + + ; /* For $this pointer */
} else {
zval * this_ptr ;
ALLOC_ZVAL ( this_ptr ) ;
* this_ptr = * EX ( object ) ;
INIT_PZVAL ( this_ptr ) ;
zval_copy_ctor ( this_ptr ) ;
EX ( object ) = this_ptr ;
}
2002-10-19 05:19:27 +08:00
}
if ( EX ( fbc ) - > type = = ZEND_USER_FUNCTION ) {
EX ( calling_scope ) = EX ( fbc ) - > common . scope ;
} else {
EX ( calling_scope ) = NULL ;
}
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_init_static_method_call_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * function_name ;
zval tmp ;
zend_class_entry * ce ;
zend_bool is_const ;
char * function_name_strval ;
int function_name_strlen ;
zend_ptr_stack_n_push ( & EG ( arg_types_stack ) , 3 , EX ( fbc ) , EX ( object ) , EX ( calling_scope ) ) ;
is_const = ( EX ( opline ) - > op2 . op_type = = IS_CONST ) ;
if ( is_const ) {
function_name_strval = EX ( opline ) - > op2 . u . constant . value . str . val ;
function_name_strlen = EX ( opline ) - > op2 . u . constant . value . str . len ;
} else {
function_name = get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
tmp = * function_name ;
zval_copy_ctor ( & tmp ) ;
convert_to_string ( & tmp ) ;
zend_str_tolower ( tmp . value . str . val , tmp . value . str . len ) ;
function_name_strval = tmp . value . str . val ;
function_name_strlen = tmp . value . str . len ;
}
2003-03-12 07:19:45 +08:00
if ( EX ( opline ) - > op1 . op_type = = IS_UNUSED ) {
ce = EG ( global_namespace_ptr ) ;
} else {
ce = EX_T ( EX ( opline ) - > op1 . u . var ) . EA . class_entry ;
}
2002-10-19 05:19:27 +08:00
2003-02-17 22:06:39 +08:00
EX ( fbc ) = zend_std_get_static_method ( ce , function_name_strval , function_name_strlen TSRMLS_CC ) ;
2002-12-07 01:09:44 +08:00
EX ( calling_scope ) = EX ( fbc ) - > common . scope ;
2002-10-19 05:19:27 +08:00
if ( ! is_const ) {
zval_dtor ( & tmp ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
}
2002-12-07 01:09:44 +08:00
if ( EX ( fbc ) - > common . fn_flags & ZEND_ACC_STATIC ) {
2002-11-06 03:37:31 +08:00
EX ( object ) = NULL ;
} else {
if ( ( EX ( object ) = EG ( This ) ) ) {
EX ( object ) - > refcount + + ;
}
}
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_init_fcall_by_name_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * function_name ;
zend_function * function ;
zval tmp ;
zend_bool is_const ;
char * function_name_strval ;
int function_name_strlen ;
zend_ptr_stack_n_push ( & EG ( arg_types_stack ) , 3 , EX ( fbc ) , EX ( object ) , EX ( calling_scope ) ) ;
is_const = ( EX ( opline ) - > op2 . op_type = = IS_CONST ) ;
if ( is_const ) {
function_name_strval = EX ( opline ) - > op2 . u . constant . value . str . val ;
function_name_strlen = EX ( opline ) - > op2 . u . constant . value . str . len ;
} else {
function_name = get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
tmp = * function_name ;
zval_copy_ctor ( & tmp ) ;
convert_to_string ( & tmp ) ;
zend_str_tolower ( tmp . value . str . val , tmp . value . str . len ) ;
function_name_strval = tmp . value . str . val ;
function_name_strlen = tmp . value . str . len ;
}
do {
/*
if ( EG ( scope ) ) {
if ( zend_hash_find ( & EG ( scope ) - > function_table , function_name_strval , function_name_strlen + 1 , ( void * * ) & function ) = = SUCCESS ) {
if ( ( EX ( object ) = EG ( This ) ) ) {
EX ( object ) - > refcount + + ;
}
EX ( calling_scope ) = EG ( scope ) ;
break ;
}
}
*/
if ( zend_hash_find ( EG ( function_table ) , function_name_strval , function_name_strlen + 1 , ( void * * ) & function ) = = FAILURE ) {
2003-02-16 19:12:43 +08:00
/* try global space also */
if ( zend_hash_find ( & EG ( global_namespace_ptr ) - > function_table , function_name_strval , function_name_strlen + 1 , ( void * * ) & function ) = = FAILURE ) {
zend_error ( E_ERROR , " Call to undefined function: %s() " , function_name_strval ) ;
}
2002-10-19 05:19:27 +08:00
}
EX ( calling_scope ) = function - > common . scope ;
EX ( object ) = NULL ;
} while ( 0 ) ;
if ( ! is_const ) {
zval_dtor ( & tmp ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
}
EX ( fbc ) = function ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_do_fcall_common_helper ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * * original_return_value ;
zend_class_entry * current_scope ;
zval * current_this ;
int return_value_used = RETURN_VALUE_USED ( EX ( opline ) ) ;
2003-02-16 19:12:43 +08:00
zend_namespace * active_namespace = EG ( active_namespace ) ;
2002-10-19 05:19:27 +08:00
zend_ptr_stack_n_push ( & EG ( argument_stack ) , 2 , ( void * ) EX ( opline ) - > extended_value , NULL ) ;
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr = & EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ;
2002-10-19 05:19:27 +08:00
2003-02-17 03:10:27 +08:00
current_this = EG ( This ) ;
EG ( This ) = EX ( object ) ;
current_scope = EG ( scope ) ;
EG ( scope ) = EX ( calling_scope ) ;
2002-11-06 03:37:31 +08:00
if ( EX ( function_state ) . function - > type = = ZEND_INTERNAL_FUNCTION ) {
2002-10-24 04:26:28 +08:00
ALLOC_ZVAL ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) ;
INIT_ZVAL ( * ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) ) ;
2003-01-12 00:12:44 +08:00
2003-01-12 01:04:16 +08:00
if ( ! zend_execute_internal ) {
/* saves one function call if zend_execute_internal is not used */
2003-01-12 00:12:44 +08:00
( ( zend_internal_function * ) EX ( function_state ) . function ) - > handler ( EX ( opline ) - > extended_value , EX_T ( EX ( opline ) - > result . u . var ) . var . ptr , EX ( object ) , return_value_used TSRMLS_CC ) ;
} else {
zend_execute_internal ( execute_data , return_value_used TSRMLS_CC ) ;
}
2002-10-19 05:19:27 +08:00
EG ( current_execute_data ) = execute_data ;
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr - > is_ref = 0 ;
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr - > refcount = 1 ;
2002-10-19 05:19:27 +08:00
if ( ! return_value_used ) {
2002-10-24 04:26:28 +08:00
zval_ptr_dtor ( & EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) ;
2002-10-19 05:19:27 +08:00
}
2002-11-06 03:37:31 +08:00
} else if ( EX ( function_state ) . function - > type = = ZEND_USER_FUNCTION ) {
2002-10-19 05:19:27 +08:00
HashTable * calling_symbol_table ;
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr = NULL ;
2002-10-19 05:19:27 +08:00
if ( EG ( symtable_cache_ptr ) > = EG ( symtable_cache ) ) {
/*printf("Cache hit! Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/
EX ( function_state ) . function_symbol_table = * ( EG ( symtable_cache_ptr ) - - ) ;
} else {
ALLOC_HASHTABLE ( EX ( function_state ) . function_symbol_table ) ;
zend_hash_init ( EX ( function_state ) . function_symbol_table , 0 , NULL , ZVAL_PTR_DTOR , 0 ) ;
/*printf("Cache miss! Initialized %x\n", function_state.function_symbol_table);*/
}
calling_symbol_table = EG ( active_symbol_table ) ;
EG ( active_symbol_table ) = EX ( function_state ) . function_symbol_table ;
original_return_value = EG ( return_value_ptr_ptr ) ;
2002-10-24 04:26:28 +08:00
EG ( return_value_ptr_ptr ) = EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr ;
2002-10-19 05:19:27 +08:00
EG ( active_op_array ) = ( zend_op_array * ) EX ( function_state ) . function ;
zend_execute ( EG ( active_op_array ) TSRMLS_CC ) ;
2002-10-24 04:26:28 +08:00
if ( return_value_used & & ! EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) {
2002-10-19 05:19:27 +08:00
if ( ! EG ( exception ) ) {
2002-10-24 04:26:28 +08:00
ALLOC_ZVAL ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) ;
INIT_ZVAL ( * EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) ;
2002-10-19 05:19:27 +08:00
}
2002-10-24 04:26:28 +08:00
} else if ( ! return_value_used & & EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) {
zval_ptr_dtor ( & EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) ;
2002-10-19 05:19:27 +08:00
}
EG ( opline_ptr ) = & EX ( opline ) ;
EG ( active_op_array ) = op_array ;
EG ( return_value_ptr_ptr ) = original_return_value ;
if ( EG ( symtable_cache_ptr ) > = EG ( symtable_cache_limit ) ) {
zend_hash_destroy ( EX ( function_state ) . function_symbol_table ) ;
FREE_HASHTABLE ( EX ( function_state ) . function_symbol_table ) ;
} else {
* ( + + EG ( symtable_cache_ptr ) ) = EX ( function_state ) . function_symbol_table ;
zend_hash_clean ( * EG ( symtable_cache_ptr ) ) ;
}
EG ( active_symbol_table ) = calling_symbol_table ;
} else { /* ZEND_OVERLOADED_FUNCTION */
2002-10-24 04:26:28 +08:00
ALLOC_ZVAL ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) ;
INIT_ZVAL ( * ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) ) ;
2002-10-19 05:19:27 +08:00
2003-02-17 03:10:27 +08:00
/* Not sure what should be done here if it's a static method */
2002-10-19 05:19:27 +08:00
if ( EX ( object ) ) {
2002-10-24 04:26:28 +08:00
Z_OBJ_HT_P ( EX ( object ) ) - > call_method ( EX ( fbc ) - > common . function_name , EX ( opline ) - > extended_value , EX_T ( EX ( opline ) - > result . u . var ) . var . ptr , EX ( object ) , return_value_used TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
} else {
zend_error ( E_ERROR , " Cannot call overloaded function for non-object " ) ;
}
efree ( EX ( fbc ) ) ;
if ( ! return_value_used ) {
2002-10-24 04:26:28 +08:00
zval_ptr_dtor ( & EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) ;
2002-10-19 05:19:27 +08:00
}
}
2003-02-17 03:10:27 +08:00
if ( EG ( This ) ) {
zval_ptr_dtor ( & EG ( This ) ) ;
}
EG ( This ) = current_this ;
EG ( scope ) = current_scope ;
2002-10-19 05:19:27 +08:00
zend_ptr_stack_n_pop ( & EG ( arg_types_stack ) , 3 , & EX ( calling_scope ) , & EX ( object ) , & EX ( fbc ) ) ;
2003-02-16 19:12:43 +08:00
if ( EG ( active_namespace ) ! = active_namespace ) {
zend_switch_namespace ( active_namespace TSRMLS_CC ) ;
}
2002-10-19 05:19:27 +08:00
EX ( function_state ) . function = ( zend_function * ) op_array ;
EG ( function_state_ptr ) = & EX ( function_state ) ;
zend_ptr_stack_clear_multiple ( TSRMLS_C ) ;
if ( EG ( exception ) ) {
if ( EX ( opline ) - > op2 . u . opline_num = = - 1 ) {
RETURN_FROM_EXECUTE_LOOP ( execute_data ) ;
} else {
EX ( opline ) = & op_array - > opcodes [ EX ( opline ) - > op2 . u . opline_num ] ;
return 0 ; /* CHECK_ME */
}
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_do_fcall_by_name_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
EX ( function_state ) . function = EX ( fbc ) ;
return zend_do_fcall_common_helper ( ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_do_fcall_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * fname = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
zend_ptr_stack_n_push ( & EG ( arg_types_stack ) , 3 , EX ( fbc ) , EX ( object ) , EX ( calling_scope ) ) ;
do {
2002-11-06 03:37:31 +08:00
/*
2002-10-19 05:19:27 +08:00
if ( EG ( scope ) ) {
if ( zend_hash_find ( & EG ( scope ) - > function_table , fname - > value . str . val , fname - > value . str . len + 1 , ( void * * ) & EX ( function_state ) . function ) = = SUCCESS ) {
if ( ( EX ( object ) = EG ( This ) ) ) {
EX ( object ) - > refcount + + ;
}
EX ( calling_scope ) = EG ( scope ) ;
break ;
}
}
2002-11-06 03:37:31 +08:00
*/
2002-10-19 05:19:27 +08:00
if ( zend_hash_find ( EG ( function_table ) , fname - > value . str . val , fname - > value . str . len + 1 , ( void * * ) & EX ( function_state ) . function ) = = FAILURE ) {
zend_error ( E_ERROR , " Unknown function: %s() \n " , fname - > value . str . val ) ;
}
EX ( object ) = NULL ;
EX ( calling_scope ) = EX ( function_state ) . function - > common . scope ;
} while ( 0 ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
2001-12-11 02:57:17 +08:00
2002-10-19 05:19:27 +08:00
return zend_do_fcall_common_helper ( ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_return_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * retval_ptr ;
zval * * retval_ptr_ptr ;
if ( ( EG ( active_op_array ) - > return_reference = = ZEND_RETURN_REF ) & &
( EX ( opline ) - > op1 . op_type ! = IS_CONST ) & &
( EX ( opline ) - > op1 . op_type ! = IS_TMP_VAR ) ) {
retval_ptr_ptr = get_zval_ptr_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , BP_VAR_W ) ;
if ( ! retval_ptr_ptr ) {
zend_error ( E_ERROR , " Cannot return overloaded elements or string offsets by reference " ) ;
}
SEPARATE_ZVAL_TO_MAKE_IS_REF ( retval_ptr_ptr ) ;
( * retval_ptr_ptr ) - > refcount + + ;
( * EG ( return_value_ptr_ptr ) ) = ( * retval_ptr_ptr ) ;
} else {
retval_ptr = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
if ( ! EG ( free_op1 ) ) { /* Not a temp var */
if ( PZVAL_IS_REF ( retval_ptr ) & & retval_ptr - > refcount > 0 ) {
ALLOC_ZVAL ( * ( EG ( return_value_ptr_ptr ) ) ) ;
* * EG ( return_value_ptr_ptr ) = * retval_ptr ;
( * EG ( return_value_ptr_ptr ) ) - > is_ref = 0 ;
( * EG ( return_value_ptr_ptr ) ) - > refcount = 1 ;
zval_copy_ctor ( * EG ( return_value_ptr_ptr ) ) ;
} else {
* EG ( return_value_ptr_ptr ) = retval_ptr ;
retval_ptr - > refcount + + ;
}
} else {
ALLOC_ZVAL ( * ( EG ( return_value_ptr_ptr ) ) ) ;
* * EG ( return_value_ptr_ptr ) = * retval_ptr ;
( * EG ( return_value_ptr_ptr ) ) - > refcount = 1 ;
( * EG ( return_value_ptr_ptr ) ) - > is_ref = 0 ;
}
}
RETURN_FROM_EXECUTE_LOOP ( execute_data ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_throw_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * value ;
zval * exception ;
value = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
if ( value - > type ! = IS_OBJECT ) {
zend_error ( E_ERROR , " Can only throw objects " ) ;
}
/* Not sure if a complete copy is what we want here */
MAKE_STD_ZVAL ( exception ) ;
* exception = * value ;
if ( ! EG ( free_op1 ) ) {
zval_copy_ctor ( exception ) ;
}
INIT_PZVAL ( exception ) ;
EG ( exception ) = exception ;
if ( EX ( opline ) - > op2 . u . opline_num = = - 1 ) {
RETURN_FROM_EXECUTE_LOOP ( execute_data ) ;
} else {
EX ( opline ) = & op_array - > opcodes [ EX ( opline ) - > op2 . u . opline_num ] ;
return 0 ; /* CHECK_ME */
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_catch_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_class_entry * ce ;
/* Check if this is really an exception, if not, jump over code */
if ( EG ( exception ) = = NULL ) {
EX ( opline ) = & op_array - > opcodes [ EX ( opline ) - > extended_value ] ;
return 0 ; /* CHECK_ME */
}
ce = Z_OBJCE_P ( EG ( exception ) ) ;
2002-10-24 04:26:28 +08:00
if ( ce ! = EX_T ( EX ( opline ) - > op1 . u . var ) . EA . class_entry ) {
2002-10-19 05:19:27 +08:00
while ( ce - > parent ) {
2002-10-24 04:26:28 +08:00
if ( ce - > parent = = EX_T ( EX ( opline ) - > op1 . u . var ) . EA . class_entry ) {
2002-10-19 05:19:27 +08:00
goto exception_should_be_taken ;
}
ce = ce - > parent ;
}
EX ( opline ) = & op_array - > opcodes [ EX ( opline ) - > extended_value ] ;
return 0 ; /* CHECK_ME */
}
exception_should_be_taken :
zend_hash_update ( EG ( active_symbol_table ) , EX ( opline ) - > op2 . u . constant . value . str . val ,
EX ( opline ) - > op2 . u . constant . value . str . len + 1 , & EG ( exception ) , sizeof ( zval * ) , ( void * * ) NULL ) ;
EG ( exception ) = NULL ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_send_val_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
if ( EX ( opline ) - > extended_value = = ZEND_DO_FCALL_BY_NAME
& & ARG_SHOULD_BE_SENT_BY_REF ( EX ( opline ) - > op2 . u . opline_num , EX ( fbc ) , EX ( fbc ) - > common . arg_types ) ) {
zend_error ( E_ERROR , " Cannot pass parameter %d by reference " , EX ( opline ) - > op2 . u . opline_num ) ;
}
{
zval * valptr ;
zval * value ;
value = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
ALLOC_ZVAL ( valptr ) ;
* valptr = * value ;
if ( ! EG ( free_op1 ) ) {
zval_copy_ctor ( valptr ) ;
}
INIT_PZVAL ( valptr ) ;
zend_ptr_stack_push ( & EG ( argument_stack ) , valptr ) ;
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
inline int zend_send_by_var_helper ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * varptr ;
varptr = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
if ( varptr = = & EG ( uninitialized_zval ) ) {
ALLOC_ZVAL ( varptr ) ;
INIT_ZVAL ( * varptr ) ;
varptr - > refcount = 0 ;
} else if ( PZVAL_IS_REF ( varptr ) ) {
zval * original_var = varptr ;
ALLOC_ZVAL ( varptr ) ;
* varptr = * original_var ;
varptr - > is_ref = 0 ;
varptr - > refcount = 0 ;
zval_copy_ctor ( varptr ) ;
}
varptr - > refcount + + ;
zend_ptr_stack_push ( & EG ( argument_stack ) , varptr ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ; /* for string offsets */
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_send_var_no_ref_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
if ( EX ( opline ) - > extended_value & ZEND_ARG_COMPILE_TIME_BOUND ) { /* Had function_ptr at compile_time */
if ( ! ( EX ( opline ) - > extended_value & ZEND_ARG_SEND_BY_REF ) ) {
return zend_send_by_var_helper ( ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
} else if ( ! ARG_SHOULD_BE_SENT_BY_REF ( EX ( opline ) - > op2 . u . opline_num , EX ( fbc ) , EX ( fbc ) - > common . arg_types ) ) {
return zend_send_by_var_helper ( ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
{
zval * varptr ;
varptr = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
if ( varptr ! = & EG ( uninitialized_zval ) & & ( PZVAL_IS_REF ( varptr ) | | varptr - > refcount = = 1 ) ) {
varptr - > is_ref = 1 ;
varptr - > refcount + + ;
zend_ptr_stack_push ( & EG ( argument_stack ) , varptr ) ;
NEXT_OPCODE ( ) ;
}
zend_error ( E_ERROR , " Only variables can be passed by reference " ) ;
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_send_ref_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * * varptr_ptr ;
zval * varptr ;
varptr_ptr = get_zval_ptr_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , BP_VAR_W ) ;
if ( ! varptr_ptr ) {
zend_error ( E_ERROR , " Only variables can be passed by reference " ) ;
}
SEPARATE_ZVAL_TO_MAKE_IS_REF ( varptr_ptr ) ;
varptr = * varptr_ptr ;
varptr - > refcount + + ;
zend_ptr_stack_push ( & EG ( argument_stack ) , varptr ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_send_var_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
if ( ( EX ( opline ) - > extended_value = = ZEND_DO_FCALL_BY_NAME )
& & ARG_SHOULD_BE_SENT_BY_REF ( EX ( opline ) - > op2 . u . opline_num , EX ( fbc ) , EX ( fbc ) - > common . arg_types ) ) {
return zend_send_ref_handler ( ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
return zend_send_by_var_helper ( ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_recv_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * * param ;
if ( zend_ptr_stack_get_arg ( EX ( opline ) - > op1 . u . constant . value . lval , ( void * * ) & param TSRMLS_CC ) = = FAILURE ) {
zend_error ( E_WARNING , " Missing argument %d for %s() \n " , EX ( opline ) - > op1 . u . constant . value . lval , get_active_function_name ( TSRMLS_C ) ) ;
if ( EX ( opline ) - > result . op_type = = IS_VAR ) {
2002-10-24 04:26:28 +08:00
PZVAL_UNLOCK ( * EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr ) ;
2002-10-19 05:19:27 +08:00
}
} else if ( PZVAL_IS_REF ( * param ) ) {
2003-03-06 22:31:17 +08:00
zend_assign_to_variable_reference ( & EX ( opline ) - > result , get_zval_ptr_ptr ( & EX ( opline ) - > result , EX ( Ts ) , BP_VAR_W ) , param , NULL TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
} else {
2003-03-06 22:31:17 +08:00
zend_assign_to_variable ( & EX ( opline ) - > result , & EX ( opline ) - > result , NULL , * param , IS_VAR , EX ( Ts ) TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_recv_init_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * * param , * assignment_value ;
if ( zend_ptr_stack_get_arg ( EX ( opline ) - > op1 . u . constant . value . lval , ( void * * ) & param TSRMLS_CC ) = = FAILURE ) {
if ( EX ( opline ) - > op2 . u . constant . type = = IS_CONSTANT | | EX ( opline ) - > op2 . u . constant . type = = IS_CONSTANT_ARRAY ) {
zval * default_value ;
ALLOC_ZVAL ( default_value ) ;
* default_value = EX ( opline ) - > op2 . u . constant ;
if ( EX ( opline ) - > op2 . u . constant . type = = IS_CONSTANT_ARRAY ) {
zval_copy_ctor ( default_value ) ;
}
default_value - > refcount = 1 ;
zval_update_constant ( & default_value , 0 TSRMLS_CC ) ;
default_value - > refcount = 0 ;
default_value - > is_ref = 0 ;
param = & default_value ;
assignment_value = default_value ;
} else {
param = NULL ;
assignment_value = & EX ( opline ) - > op2 . u . constant ;
}
2003-03-06 22:31:17 +08:00
zend_assign_to_variable ( & EX ( opline ) - > result , & EX ( opline ) - > result , NULL , assignment_value , IS_VAR , EX ( Ts ) TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
} else {
assignment_value = * param ;
if ( PZVAL_IS_REF ( assignment_value ) ) {
2003-03-06 22:31:17 +08:00
zend_assign_to_variable_reference ( & EX ( opline ) - > result , get_zval_ptr_ptr ( & EX ( opline ) - > result , EX ( Ts ) , BP_VAR_W ) , param , NULL TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
} else {
2003-03-06 22:31:17 +08:00
zend_assign_to_variable ( & EX ( opline ) - > result , & EX ( opline ) - > result , NULL , assignment_value , IS_VAR , EX ( Ts ) TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
}
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_bool_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
/* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . value . lval = zend_is_true ( get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ) ;
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . type = IS_BOOL ;
2002-10-19 05:19:27 +08:00
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
2002-01-04 14:44:19 +08:00
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2002-01-04 16:05:21 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
inline int zend_brk_cont_helper ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * nest_levels_zval = get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
zval tmp ;
int array_offset , nest_levels , original_nest_levels ;
zend_brk_cont_element * jmp_to ;
if ( nest_levels_zval - > type ! = IS_LONG ) {
tmp = * nest_levels_zval ;
zval_copy_ctor ( & tmp ) ;
convert_to_long ( & tmp ) ;
nest_levels = tmp . value . lval ;
} else {
nest_levels = nest_levels_zval - > value . lval ;
}
original_nest_levels = nest_levels ;
array_offset = EX ( opline ) - > op1 . u . opline_num ;
do {
if ( array_offset = = - 1 ) {
zend_error ( E_ERROR , " Cannot break/continue %d level%s " , original_nest_levels , ( original_nest_levels = = 1 ) ? " " : " s " ) ;
}
jmp_to = & op_array - > brk_cont_array [ array_offset ] ;
if ( nest_levels > 1 ) {
zend_op * brk_opline = & op_array - > opcodes [ jmp_to - > brk ] ;
2002-01-07 03:52:22 +08:00
2002-10-19 05:19:27 +08:00
switch ( brk_opline - > opcode ) {
case ZEND_SWITCH_FREE :
zend_switch_free ( brk_opline , EX ( Ts ) TSRMLS_CC ) ;
break ;
case ZEND_FREE :
2002-10-24 04:26:28 +08:00
zendi_zval_dtor ( EX_T ( brk_opline - > op1 . u . var ) . tmp_var ) ;
2002-10-19 05:19:27 +08:00
break ;
}
}
array_offset = jmp_to - > parent ;
} while ( - - nest_levels > 0 ) ;
1999-08-16 03:29:39 +08:00
2002-10-19 05:19:27 +08:00
if ( EX ( opline ) - > opcode = = ZEND_BRK ) {
EX ( opline ) = op_array - > opcodes + jmp_to - > brk ;
} else {
EX ( opline ) = op_array - > opcodes + jmp_to - > cont ;
}
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
return 0 ; /* CHECK_ME */
}
2001-08-30 23:26:30 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_brk_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_brk_cont_helper ( ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2002-02-07 22:08:43 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_cont_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_brk_cont_helper ( ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2001-08-30 23:26:30 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_case_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
int switch_expr_is_overloaded = 0 ;
2001-12-11 02:57:17 +08:00
2002-10-19 05:19:27 +08:00
if ( EX ( opline ) - > op1 . op_type = = IS_VAR ) {
2002-10-24 04:26:28 +08:00
if ( EX_T ( EX ( opline ) - > op1 . u . var ) . var . ptr_ptr ) {
PZVAL_LOCK ( * EX_T ( EX ( opline ) - > op1 . u . var ) . var . ptr_ptr ) ;
2002-10-19 05:19:27 +08:00
} else {
switch_expr_is_overloaded = 1 ;
2002-10-24 04:26:28 +08:00
if ( EX_T ( EX ( opline ) - > op1 . u . var ) . EA . type = = IS_STRING_OFFSET ) {
EX_T ( EX ( opline ) - > op1 . u . var ) . EA . data . str_offset . str - > refcount + + ;
2002-10-19 05:19:27 +08:00
}
}
}
2002-10-24 04:26:28 +08:00
is_equal_function ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ,
2002-10-19 05:19:27 +08:00
get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
if ( switch_expr_is_overloaded ) {
/* We only free op1 if this is a string offset,
* Since if it is a TMP_VAR , it ' ll be reused by
* other CASE opcodes ( whereas string offsets
* are allocated at each get_zval_ptr ( ) )
*/
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > op1 . u . var ) . var . ptr_ptr = NULL ;
AI_USE_PTR ( EX_T ( EX ( opline ) - > op1 . u . var ) . var ) ;
2002-10-19 05:19:27 +08:00
}
NEXT_OPCODE ( ) ;
}
2002-01-05 23:18:30 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_switch_free_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_switch_free ( EX ( opline ) , EX ( Ts ) TSRMLS_CC ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_new_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-03-07 06:53:23 +08:00
if ( EX_T ( EX ( opline ) - > op1 . u . var ) . EA . class_entry - > ce_flags & ( ZEND_ACC_INTERFACE | ZEND_ACC_ABSTRACT_CLASS ) ) {
2003-03-05 19:14:44 +08:00
char * class_type ;
if ( EX_T ( EX ( opline ) - > op1 . u . var ) . EA . class_entry - > ce_flags & ZEND_ACC_INTERFACE ) {
class_type = " interface " ;
} else {
2003-03-07 07:09:57 +08:00
class_type = " abstract class " ;
2003-03-05 19:14:44 +08:00
}
2003-03-05 21:25:33 +08:00
zend_error ( E_ERROR , " Cannot instantiate %s %s " , class_type , EX_T ( EX ( opline ) - > op1 . u . var ) . EA . class_entry - > name ) ;
2002-12-07 01:09:44 +08:00
}
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr = & EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ;
ALLOC_ZVAL ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) ;
object_init_ex ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr , EX_T ( EX ( opline ) - > op1 . u . var ) . EA . class_entry ) ;
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr - > refcount = 1 ;
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr - > is_ref = 1 ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_clone_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * obj = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2003-05-20 01:12:56 +08:00
if ( Z_TYPE_P ( obj ) ! = IS_OBJECT ) {
zend_error ( E_WARNING , " __clone method called on non-object " ) ;
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr = EG ( error_zval_ptr ) ;
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr - > refcount + + ;
NEXT_OPCODE ( ) ;
}
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr = & EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ;
ALLOC_ZVAL ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) ;
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr - > value . obj = Z_OBJ_HT_P ( obj ) - > clone_obj ( obj TSRMLS_CC ) ;
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr - > type = IS_OBJECT ;
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr - > refcount = 1 ;
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr - > is_ref = 1 ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_constant_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-02-16 19:12:43 +08:00
zend_class_entry * ce = NULL ;
2002-10-19 05:19:27 +08:00
zval * * value ;
if ( EX ( opline ) - > op1 . op_type = = IS_UNUSED ) {
if ( EG ( scope ) ) {
ce = EG ( scope ) ;
if ( zend_hash_find ( & ce - > constants_table , EX ( opline ) - > op2 . u . constant . value . str . val , EX ( opline ) - > op2 . u . constant . value . str . len + 1 , ( void * * ) & value ) = = SUCCESS ) {
zval_update_constant ( value , ( void * ) 1 TSRMLS_CC ) ;
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var = * * value ;
zval_copy_ctor ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ) ;
2000-01-29 08:33:07 +08:00
NEXT_OPCODE ( ) ;
2002-10-19 05:19:27 +08:00
}
}
2003-02-16 19:12:43 +08:00
if ( EG ( active_namespace ) ! = EG ( global_namespace_ptr ) ) {
/* if we are not global, go find in local constant table */
if ( zend_hash_find ( & EG ( active_namespace ) - > constants_table , EX ( opline ) - > op2 . u . constant . value . str . val , EX ( opline ) - > op2 . u . constant . value . str . len + 1 , ( void * * ) & value ) = = SUCCESS ) {
zval_update_constant ( value , ( void * ) 1 TSRMLS_CC ) ;
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var = * * value ;
zval_copy_ctor ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ) ;
NEXT_OPCODE ( ) ;
}
}
2002-10-24 04:26:28 +08:00
if ( ! zend_get_constant ( EX ( opline ) - > op2 . u . constant . value . str . val , EX ( opline ) - > op2 . u . constant . value . str . len , & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var TSRMLS_CC ) ) {
2002-10-19 05:19:27 +08:00
zend_error ( E_NOTICE , " Use of undefined constant %s - assumed '%s' " ,
EX ( opline ) - > op2 . u . constant . value . str . val ,
EX ( opline ) - > op2 . u . constant . value . str . val ) ;
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var = EX ( opline ) - > op2 . u . constant ;
zval_copy_ctor ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ) ;
2002-10-19 05:19:27 +08:00
}
NEXT_OPCODE ( ) ;
}
2002-10-24 04:26:28 +08:00
ce = EX_T ( EX ( opline ) - > op1 . u . var ) . EA . class_entry ;
2002-10-19 05:19:27 +08:00
2003-02-16 19:12:43 +08:00
if ( & ce - > constants_table = = & EG ( global_namespace_ptr ) - > constants_table ) {
2002-10-24 04:26:28 +08:00
if ( ! zend_get_constant ( EX ( opline ) - > op2 . u . constant . value . str . val , EX ( opline ) - > op2 . u . constant . value . str . len , & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var TSRMLS_CC ) ) {
2002-10-19 05:19:27 +08:00
zend_error ( E_NOTICE , " Use of undefined constant %s - assumed '%s' " ,
EX ( opline ) - > op2 . u . constant . value . str . val ,
EX ( opline ) - > op2 . u . constant . value . str . val ) ;
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var = EX ( opline ) - > op2 . u . constant ;
zval_copy_ctor ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ) ;
2002-10-19 05:19:27 +08:00
}
NEXT_OPCODE ( ) ;
}
if ( zend_hash_find ( & ce - > constants_table , EX ( opline ) - > op2 . u . constant . value . str . val , EX ( opline ) - > op2 . u . constant . value . str . len + 1 , ( void * * ) & value ) = = SUCCESS ) {
zval_update_constant ( value , ( void * ) 1 TSRMLS_CC ) ;
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var = * * value ;
zval_copy_ctor ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ) ;
2002-10-19 05:19:27 +08:00
} else {
zend_error ( E_ERROR , " Undefined class constant '%s' " , EX ( opline ) - > op2 . u . constant . value . str . val ) ;
}
2002-08-03 17:44:27 +08:00
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
inline int zend_init_add_array_helper ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-24 04:26:28 +08:00
zval * array_ptr = & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ;
2002-10-19 05:19:27 +08:00
zval * expr_ptr , * * expr_ptr_ptr = NULL ;
zval * offset = get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
if ( EX ( opline ) - > extended_value ) {
expr_ptr_ptr = get_zval_ptr_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , BP_VAR_R ) ;
expr_ptr = * expr_ptr_ptr ;
} else {
expr_ptr = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
}
if ( EX ( opline ) - > opcode = = ZEND_INIT_ARRAY ) {
array_init ( array_ptr ) ;
if ( ! expr_ptr ) {
NEXT_OPCODE ( ) ;
}
}
if ( ! EX ( opline ) - > extended_value & & EG ( free_op1 ) ) { /* temporary variable */
zval * new_expr ;
ALLOC_ZVAL ( new_expr ) ;
* new_expr = * expr_ptr ;
expr_ptr = new_expr ;
INIT_PZVAL ( expr_ptr ) ;
} else {
if ( EX ( opline ) - > extended_value ) {
SEPARATE_ZVAL_TO_MAKE_IS_REF ( expr_ptr_ptr ) ;
expr_ptr = * expr_ptr_ptr ;
expr_ptr - > refcount + + ;
} else if ( PZVAL_IS_REF ( expr_ptr ) ) {
zval * new_expr ;
ALLOC_ZVAL ( new_expr ) ;
* new_expr = * expr_ptr ;
expr_ptr = new_expr ;
zendi_zval_copy_ctor ( * expr_ptr ) ;
INIT_PZVAL ( expr_ptr ) ;
} else {
expr_ptr - > refcount + + ;
}
}
if ( offset ) {
2002-11-30 19:20:25 +08:00
switch ( offset - > type ) {
2002-10-19 05:19:27 +08:00
case IS_DOUBLE :
zend_hash_index_update ( array_ptr - > value . ht , ( long ) offset - > value . dval , & expr_ptr , sizeof ( zval * ) , NULL ) ;
break ;
case IS_LONG :
2003-01-22 22:48:30 +08:00
case IS_BOOL :
2002-10-19 05:19:27 +08:00
zend_hash_index_update ( array_ptr - > value . ht , offset - > value . lval , & expr_ptr , sizeof ( zval * ) , NULL ) ;
break ;
case IS_STRING :
zend_hash_update ( array_ptr - > value . ht , offset - > value . str . val , offset - > value . str . len + 1 , & expr_ptr , sizeof ( zval * ) , NULL ) ;
break ;
case IS_NULL :
zend_hash_update ( array_ptr - > value . ht , " " , sizeof ( " " ) , & expr_ptr , sizeof ( zval * ) , NULL ) ;
1999-04-08 02:10:10 +08:00
break ;
2002-10-19 05:19:27 +08:00
default :
zval_ptr_dtor ( & expr_ptr ) ;
/* do nothing */
break ;
}
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
} else {
zend_hash_next_index_insert ( array_ptr - > value . ht , & expr_ptr , sizeof ( zval * ) , NULL ) ;
}
NEXT_OPCODE ( ) ;
}
2001-08-30 23:26:30 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_init_array_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_init_add_array_helper ( ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_add_array_element_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
return zend_init_add_array_helper ( ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_cast_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * expr = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2002-10-24 04:26:28 +08:00
zval * result = & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ;
2002-10-19 05:19:27 +08:00
* result = * expr ;
if ( ! EG ( free_op1 ) ) {
zendi_zval_copy_ctor ( * result ) ;
}
switch ( EX ( opline ) - > extended_value ) {
case IS_NULL :
convert_to_null ( result ) ;
break ;
case IS_BOOL :
convert_to_boolean ( result ) ;
break ;
case IS_LONG :
convert_to_long ( result ) ;
break ;
case IS_DOUBLE :
convert_to_double ( result ) ;
break ;
case IS_STRING :
convert_to_string ( result ) ;
break ;
case IS_ARRAY :
convert_to_array ( result ) ;
break ;
case IS_OBJECT :
convert_to_object ( result ) ;
break ;
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_include_or_eval_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_op_array * new_op_array = NULL ;
zval * * original_return_value = EG ( return_value_ptr_ptr ) ;
int return_value_used ;
zval * inc_filename = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
zval tmp_inc_filename ;
zend_bool failure_retval = 0 ;
if ( inc_filename - > type ! = IS_STRING ) {
tmp_inc_filename = * inc_filename ;
zval_copy_ctor ( & tmp_inc_filename ) ;
convert_to_string ( & tmp_inc_filename ) ;
inc_filename = & tmp_inc_filename ;
}
return_value_used = RETURN_VALUE_USED ( EX ( opline ) ) ;
switch ( EX ( opline ) - > op2 . u . constant . value . lval ) {
case ZEND_INCLUDE_ONCE :
case ZEND_REQUIRE_ONCE : {
int dummy = 1 ;
zend_file_handle file_handle ;
2003-02-18 17:37:54 +08:00
if ( SUCCESS = = zend_stream_open ( inc_filename - > value . str . val , & file_handle TSRMLS_CC ) ) {
2002-10-19 05:19:27 +08:00
2003-02-18 17:37:54 +08:00
if ( ! file_handle . opened_path ) {
file_handle . opened_path = estrndup ( inc_filename - > value . str . val , inc_filename - > value . str . len ) ;
2002-10-19 05:19:27 +08:00
}
2003-02-18 17:37:54 +08:00
if ( zend_hash_add ( & EG ( included_files ) , file_handle . opened_path , strlen ( file_handle . opened_path ) + 1 , ( void * ) & dummy , sizeof ( int ) , NULL ) = = SUCCESS ) {
2003-03-27 04:42:23 +08:00
CG ( active_namespace ) = EG ( global_namespace_ptr ) ;
2002-10-19 05:19:27 +08:00
new_op_array = zend_compile_file ( & file_handle , ( EX ( opline ) - > op2 . u . constant . value . lval = = ZEND_INCLUDE_ONCE ? ZEND_INCLUDE : ZEND_REQUIRE ) TSRMLS_CC ) ;
zend_destroy_file_handle ( & file_handle TSRMLS_CC ) ;
} else {
2003-02-18 17:37:54 +08:00
zend_file_handle_dtor ( & file_handle ) ;
2002-10-19 05:19:27 +08:00
failure_retval = 1 ;
2001-08-30 23:26:30 +08:00
}
2002-10-19 05:19:27 +08:00
} else {
if ( EX ( opline ) - > op2 . u . constant . value . lval = = ZEND_INCLUDE_ONCE ) {
2003-03-24 19:54:42 +08:00
zend_message_dispatcher ( ZMSG_FAILED_INCLUDE_FOPEN , inc_filename - > value . str . val ) ;
2001-08-30 23:26:30 +08:00
} else {
2003-03-24 19:54:42 +08:00
zend_message_dispatcher ( ZMSG_FAILED_REQUIRE_FOPEN , inc_filename - > value . str . val ) ;
2001-08-30 23:26:30 +08:00
}
}
2002-10-19 05:19:27 +08:00
break ;
}
break ;
case ZEND_INCLUDE :
case ZEND_REQUIRE :
2003-03-27 04:42:23 +08:00
CG ( active_namespace ) = EG ( global_namespace_ptr ) ;
2002-10-19 05:19:27 +08:00
new_op_array = compile_filename ( EX ( opline ) - > op2 . u . constant . value . lval , inc_filename TSRMLS_CC ) ;
break ;
case ZEND_EVAL : {
char * eval_desc = zend_make_compiled_string_description ( " eval()'d code " TSRMLS_CC ) ;
2003-03-27 04:42:23 +08:00
CG ( active_namespace ) = EG ( global_namespace_ptr ) ;
2002-10-19 05:19:27 +08:00
new_op_array = compile_string ( inc_filename , eval_desc TSRMLS_CC ) ;
efree ( eval_desc ) ;
}
break ;
EMPTY_SWITCH_DEFAULT_CASE ( )
}
if ( inc_filename = = & tmp_inc_filename ) {
zval_dtor ( & tmp_inc_filename ) ;
}
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr = & EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ;
2002-10-19 05:19:27 +08:00
if ( new_op_array ) {
zval * saved_object ;
zend_function * saved_function ;
2003-02-16 19:12:43 +08:00
zend_namespace * active_namespace = EG ( active_namespace ) ;
2002-10-19 05:19:27 +08:00
2002-10-24 04:26:28 +08:00
EG ( return_value_ptr_ptr ) = EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr ;
2002-10-19 05:19:27 +08:00
EG ( active_op_array ) = new_op_array ;
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr = NULL ;
2002-10-19 05:19:27 +08:00
saved_object = EX ( object ) ;
saved_function = EX ( function_state ) . function ;
EX ( function_state ) . function = ( zend_function * ) new_op_array ;
EX ( object ) = NULL ;
2003-03-30 21:40:40 +08:00
zend_switch_namespace ( EG ( global_namespace_ptr ) TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
zend_execute ( new_op_array TSRMLS_CC ) ;
2003-03-27 04:42:23 +08:00
zend_switch_namespace ( active_namespace TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
EX ( function_state ) . function = saved_function ;
EX ( object ) = saved_object ;
if ( ! return_value_used ) {
2002-10-24 04:26:28 +08:00
if ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) {
zval_ptr_dtor ( & EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) ;
2002-10-19 05:19:27 +08:00
}
} else { /* return value is used */
2002-10-24 04:26:28 +08:00
if ( ! EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) { /* there was no return statement */
ALLOC_ZVAL ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) ;
INIT_PZVAL ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) ;
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr - > value . lval = 1 ;
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr - > type = IS_BOOL ;
2002-10-19 05:19:27 +08:00
}
}
EG ( opline_ptr ) = & EX ( opline ) ;
EG ( active_op_array ) = op_array ;
EG ( function_state_ptr ) = & EX ( function_state ) ;
2003-03-26 15:44:11 +08:00
destroy_op_array ( new_op_array TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
efree ( new_op_array ) ;
} else {
if ( return_value_used ) {
2002-10-24 04:26:28 +08:00
ALLOC_ZVAL ( EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) ;
INIT_ZVAL ( * EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ) ;
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr - > value . lval = failure_retval ;
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr - > type = IS_BOOL ;
2002-10-19 05:19:27 +08:00
}
}
EG ( return_value_ptr_ptr ) = original_return_value ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_unset_var_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-02-17 22:06:39 +08:00
zval tmp , * varname ;
2002-10-19 05:19:27 +08:00
HashTable * target_symbol_table ;
2003-02-17 22:06:39 +08:00
varname = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
2003-02-17 22:06:39 +08:00
if ( varname - > type ! = IS_STRING ) {
tmp = * varname ;
2002-10-19 05:19:27 +08:00
zval_copy_ctor ( & tmp ) ;
convert_to_string ( & tmp ) ;
2003-02-17 22:06:39 +08:00
varname = & tmp ;
2002-10-19 05:19:27 +08:00
}
2003-02-17 22:06:39 +08:00
if ( EX ( opline ) - > op2 . u . EA . type = = ZEND_FETCH_STATIC_MEMBER ) {
zend_std_unset_static_property ( EX_T ( EX ( opline ) - > op2 . u . var ) . EA . class_entry , Z_STRVAL_P ( varname ) , Z_STRLEN_P ( varname ) TSRMLS_CC ) ;
} else {
target_symbol_table = zend_get_target_symbol_table ( EX ( opline ) , EX ( Ts ) , BP_VAR_IS , varname TSRMLS_CC ) ;
zend_hash_del ( target_symbol_table , varname - > value . str . val , varname - > value . str . len + 1 ) ;
}
2002-10-19 05:19:27 +08:00
2003-02-17 22:06:39 +08:00
if ( varname = = & tmp ) {
2002-10-19 05:19:27 +08:00
zval_dtor ( & tmp ) ;
}
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_unset_dim_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-11-01 15:59:42 +08:00
zval * * container = get_obj_zval_ptr_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
zval * offset = get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
if ( container ) {
HashTable * ht ;
if ( ( * container ) - > type = = IS_ARRAY ) {
ht = ( * container ) - > value . ht ;
} else {
ht = NULL ;
if ( ( * container ) - > type = = IS_OBJECT ) {
Z_OBJ_HT_P ( * container ) - > unset_property ( * container , offset TSRMLS_CC ) ;
}
}
if ( ht ) {
switch ( offset - > type ) {
case IS_DOUBLE :
case IS_RESOURCE :
case IS_BOOL :
case IS_LONG :
{
long index ;
if ( offset - > type = = IS_DOUBLE ) {
index = ( long ) offset - > value . lval ;
} else {
index = offset - > value . lval ;
2002-01-14 04:21:55 +08:00
}
2002-10-19 05:19:27 +08:00
zend_hash_index_del ( ht , index ) ;
break ;
2002-01-14 04:21:55 +08:00
}
2002-10-19 05:19:27 +08:00
case IS_STRING :
zend_hash_del ( ht , offset - > value . str . val , offset - > value . str . len + 1 ) ;
break ;
case IS_NULL :
zend_hash_del ( ht , " " , sizeof ( " " ) ) ;
break ;
default :
zend_error ( E_WARNING , " Illegal offset type in unset " ) ;
break ;
}
}
} else {
/* overloaded element */
}
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fe_reset_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * array_ptr , * * array_ptr_ptr ;
HashTable * fe_ht ;
if ( EX ( opline ) - > extended_value ) {
array_ptr_ptr = get_zval_ptr_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , BP_VAR_R ) ;
if ( array_ptr_ptr = = NULL ) {
MAKE_STD_ZVAL ( array_ptr ) ;
} else {
SEPARATE_ZVAL_IF_NOT_REF ( array_ptr_ptr ) ;
array_ptr = * array_ptr_ptr ;
array_ptr - > refcount + + ;
}
} else {
array_ptr = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
if ( EG ( free_op1 ) ) { /* IS_TMP_VAR */
zval * tmp ;
ALLOC_ZVAL ( tmp ) ;
* tmp = * array_ptr ;
INIT_PZVAL ( tmp ) ;
array_ptr = tmp ;
} else {
array_ptr - > refcount + + ;
}
}
PZVAL_LOCK ( array_ptr ) ;
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr = array_ptr ;
EX_T ( EX ( opline ) - > result . u . var ) . var . ptr_ptr = & EX_T ( EX ( opline ) - > result . u . var ) . var . ptr ;
2002-10-19 05:19:27 +08:00
if ( ( fe_ht = HASH_OF ( array_ptr ) ) ! = NULL ) {
/* probably redundant */
zend_hash_internal_pointer_reset ( fe_ht ) ;
} else {
/* JMP to the end of foreach - TBD */
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_fe_fetch_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * array = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2002-10-24 04:26:28 +08:00
zval * result = & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ;
2002-10-19 05:19:27 +08:00
zval * * value , * key ;
char * str_key ;
ulong int_key ;
HashTable * fe_ht ;
PZVAL_LOCK ( array ) ;
fe_ht = HASH_OF ( array ) ;
if ( ! fe_ht ) {
zend_error ( E_WARNING , " Invalid argument supplied for foreach() " ) ;
EX ( opline ) = op_array - > opcodes + EX ( opline ) - > op2 . u . opline_num ;
return 0 ; /* CHECK_ME */
} else if ( zend_hash_get_current_data ( fe_ht , ( void * * ) & value ) = = FAILURE ) {
EX ( opline ) = op_array - > opcodes + EX ( opline ) - > op2 . u . opline_num ;
return 0 ; /* CHECK_ME */
}
array_init ( result ) ;
( * value ) - > refcount + + ;
zend_hash_index_update ( result - > value . ht , 0 , value , sizeof ( zval * ) , NULL ) ;
ALLOC_ZVAL ( key ) ;
INIT_PZVAL ( key ) ;
switch ( zend_hash_get_current_key ( fe_ht , & str_key , & int_key , 1 ) ) {
case HASH_KEY_IS_STRING :
key - > value . str . val = str_key ;
key - > value . str . len = strlen ( str_key ) ;
key - > type = IS_STRING ;
break ;
case HASH_KEY_IS_LONG :
key - > value . lval = int_key ;
key - > type = IS_LONG ;
break ;
EMPTY_SWITCH_DEFAULT_CASE ( )
}
zend_hash_index_update ( result - > value . ht , 1 , & key , sizeof ( zval * ) , NULL ) ;
zend_hash_move_forward ( fe_ht ) ;
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_jmp_no_ctor_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * object_zval ;
zend_function * constructor ;
if ( EX ( opline ) - > op1 . op_type = = IS_VAR ) {
2002-10-24 04:26:28 +08:00
PZVAL_LOCK ( * EX_T ( EX ( opline ) - > op1 . u . var ) . var . ptr_ptr ) ;
2002-10-19 05:19:27 +08:00
}
object_zval = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
constructor = Z_OBJ_HT_P ( object_zval ) - > get_constructor ( object_zval TSRMLS_CC ) ;
EX ( fbc_constructor ) = NULL ;
if ( constructor = = NULL ) {
EX ( opline ) = op_array - > opcodes + EX ( opline ) - > op2 . u . opline_num ;
return 0 ; /* CHECK_ME */
} else {
EX ( fbc_constructor ) = constructor ;
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_isset_isempty_var_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-02-17 22:06:39 +08:00
zval tmp , * varname = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
zval * * value ;
zend_bool isset = 1 ;
HashTable * target_symbol_table ;
2003-02-17 22:06:39 +08:00
if ( varname - > type ! = IS_STRING ) {
tmp = * varname ;
2002-10-19 05:19:27 +08:00
zval_copy_ctor ( & tmp ) ;
convert_to_string ( & tmp ) ;
2003-02-17 22:06:39 +08:00
varname = & tmp ;
2002-10-19 05:19:27 +08:00
}
2003-02-17 22:06:39 +08:00
if ( EX ( opline ) - > op2 . u . EA . type = = ZEND_FETCH_STATIC_MEMBER ) {
value = zend_std_get_static_property ( EX_T ( EX ( opline ) - > op2 . u . var ) . EA . class_entry , Z_STRVAL_P ( varname ) , Z_STRLEN_P ( varname ) , 1 TSRMLS_CC ) ;
if ( ! value ) {
isset = 0 ;
}
} else {
target_symbol_table = zend_get_target_symbol_table ( EX ( opline ) , EX ( Ts ) , BP_VAR_IS , varname TSRMLS_CC ) ;
if ( zend_hash_find ( target_symbol_table , varname - > value . str . val , varname - > value . str . len + 1 , ( void * * ) & value ) = = FAILURE ) {
isset = 0 ;
}
2002-10-19 05:19:27 +08:00
}
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . type = IS_BOOL ;
2002-10-19 05:19:27 +08:00
switch ( EX ( opline ) - > extended_value ) {
case ZEND_ISSET :
if ( isset & & Z_TYPE_PP ( value ) = = IS_NULL ) {
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . value . lval = 0 ;
2002-10-19 05:19:27 +08:00
} else {
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . value . lval = isset ;
2002-10-19 05:19:27 +08:00
}
break ;
case ZEND_ISEMPTY :
if ( ! isset | | ! zend_is_true ( * value ) ) {
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . value . lval = 1 ;
2002-10-19 05:19:27 +08:00
} else {
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . value . lval = 0 ;
2002-10-19 05:19:27 +08:00
}
break ;
}
2000-11-21 04:49:42 +08:00
2003-02-17 22:06:39 +08:00
if ( varname = = & tmp ) {
2002-10-19 05:19:27 +08:00
zval_dtor ( & tmp ) ;
}
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
1999-04-08 02:10:10 +08:00
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2000-03-25 07:51:34 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_isset_isempty_dim_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-10-23 01:00:59 +08:00
zval * * container = get_obj_zval_ptr_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
zval * offset = get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
zval * * value = NULL ;
int result = 0 ;
1999-04-08 02:10:10 +08:00
2002-10-19 05:19:27 +08:00
if ( container ) {
if ( ( * container ) - > type = = IS_ARRAY ) {
HashTable * ht ;
int isset = 0 ;
1999-04-08 02:10:10 +08:00
2002-10-19 05:19:27 +08:00
ht = ( * container ) - > value . ht ;
1999-04-08 02:10:10 +08:00
2002-10-19 05:19:27 +08:00
switch ( offset - > type ) {
case IS_DOUBLE :
case IS_RESOURCE :
case IS_BOOL :
case IS_LONG :
{
long index ;
1999-07-24 02:41:58 +08:00
2002-10-19 05:19:27 +08:00
if ( offset - > type = = IS_DOUBLE ) {
index = ( long ) offset - > value . lval ;
1999-07-24 02:41:58 +08:00
} else {
2002-10-19 05:19:27 +08:00
index = offset - > value . lval ;
2001-12-12 01:56:57 +08:00
}
2002-10-19 05:19:27 +08:00
if ( zend_hash_index_find ( ht , index , ( void * * ) & value ) = = SUCCESS ) {
isset = 1 ;
2001-12-14 00:55:04 +08:00
}
2002-10-19 05:19:27 +08:00
break ;
2001-12-14 00:55:04 +08:00
}
2002-10-19 05:19:27 +08:00
case IS_STRING :
if ( zend_hash_find ( ht , offset - > value . str . val , offset - > value . str . len + 1 , ( void * * ) & value ) = = SUCCESS ) {
isset = 1 ;
2001-12-01 00:29:47 +08:00
}
2002-10-19 05:19:27 +08:00
break ;
case IS_NULL :
if ( zend_hash_find ( ht , " " , sizeof ( " " ) , ( void * * ) & value ) = = SUCCESS ) {
isset = 1 ;
1999-10-01 18:00:05 +08:00
}
2002-10-19 05:19:27 +08:00
break ;
default :
zend_error ( E_WARNING , " Illegal offset type in unset " ) ;
1999-10-01 18:00:05 +08:00
2002-10-19 05:19:27 +08:00
break ;
}
switch ( EX ( opline ) - > extended_value ) {
case ZEND_ISSET :
if ( isset & & Z_TYPE_PP ( value ) = = IS_NULL ) {
result = 0 ;
1999-04-08 02:10:10 +08:00
} else {
2002-10-19 05:19:27 +08:00
result = isset ;
1999-04-08 02:10:10 +08:00
}
2002-10-19 05:19:27 +08:00
break ;
case ZEND_ISEMPTY :
if ( ! isset | | ! zend_is_true ( * value ) ) {
result = 0 ;
1999-04-08 02:10:10 +08:00
} else {
2002-10-19 05:19:27 +08:00
result = 1 ;
1999-04-08 02:10:10 +08:00
}
2002-10-19 05:19:27 +08:00
break ;
}
2003-01-16 08:44:17 +08:00
} else if ( ( * container ) - > type = = IS_OBJECT ) {
result = Z_OBJ_HT_P ( * container ) - > has_property ( * container , offset , ( EX ( opline ) - > extended_value = = ZEND_ISEMPTY ) TSRMLS_CC ) ;
} else if ( ( * container ) - > type = = IS_STRING ) { /* string offsets */
switch ( EX ( opline ) - > extended_value ) {
case ZEND_ISSET :
if ( offset - > value . lval < = Z_STRLEN_PP ( container ) ) {
result = 1 ;
}
break ;
case ZEND_ISEMPTY :
if ( offset - > value . lval < = Z_STRLEN_PP ( container ) & & Z_STRVAL_PP ( container ) [ offset - > value . lval ] ! = ' 0 ' ) {
result = 1 ;
}
break ;
2002-10-19 05:19:27 +08:00
}
}
}
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . type = IS_BOOL ;
2000-09-13 03:47:25 +08:00
2002-10-19 05:19:27 +08:00
switch ( EX ( opline ) - > extended_value ) {
case ZEND_ISSET :
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . value . lval = result ;
2002-10-19 05:19:27 +08:00
break ;
case ZEND_ISEMPTY :
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . value . lval = ! result ;
2002-10-19 05:19:27 +08:00
break ;
}
1999-12-19 14:39:17 +08:00
2002-10-19 05:19:27 +08:00
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op2 , EG ( free_op2 ) ) ;
1999-04-08 02:10:10 +08:00
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2002-03-15 00:00:48 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_exit_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
if ( EX ( opline ) - > op1 . op_type ! = IS_UNUSED ) {
zval * ptr ;
2002-10-17 02:29:41 +08:00
2002-10-19 05:19:27 +08:00
ptr = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
if ( Z_TYPE_P ( ptr ) = = IS_LONG ) {
EG ( exit_status ) = Z_LVAL_P ( ptr ) ;
} else {
zend_print_variable ( ptr ) ;
}
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
}
zend_bailout ( ) ;
NEXT_OPCODE ( ) ;
}
1999-04-08 02:10:10 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_begin_silence_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-11-21 02:00:23 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . value . lval = EG ( error_reporting ) ;
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var . type = IS_LONG ; /* shouldn't be necessary */
2002-11-20 01:51:30 +08:00
zend_alter_ini_entry ( " error_reporting " , sizeof ( " error_reporting " ) , " 0 " , 1 , ZEND_INI_USER , ZEND_INI_STAGE_RUNTIME ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
1999-04-08 02:10:10 +08:00
2003-02-10 19:49:21 +08:00
2002-11-21 02:00:23 +08:00
int zend_raise_abstract_error_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-11-22 14:19:04 +08:00
zend_error ( E_ERROR , " Cannot call abstract method %s::%s() " , EG ( scope ) - > name , op_array - > function_name ) ;
2002-11-21 02:00:23 +08:00
NEXT_OPCODE ( ) ; /* Never reached */
}
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_end_silence_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2002-11-20 01:51:30 +08:00
zval restored_error_reporting ;
restored_error_reporting . type = IS_LONG ;
2002-11-21 02:00:23 +08:00
restored_error_reporting . value . lval = EX_T ( EX ( opline ) - > op1 . u . var ) . tmp_var . value . lval ;
2002-11-20 01:51:30 +08:00
convert_to_string ( & restored_error_reporting ) ;
zend_alter_ini_entry ( " error_reporting " , sizeof ( " error_reporting " ) , Z_STRVAL ( restored_error_reporting ) , Z_STRLEN ( restored_error_reporting ) , ZEND_INI_USER , ZEND_INI_STAGE_RUNTIME ) ;
zendi_zval_dtor ( restored_error_reporting ) ;
2002-11-21 02:00:23 +08:00
NEXT_OPCODE ( ) ;
2002-10-19 05:19:27 +08:00
}
2000-01-25 03:04:07 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_qm_assign_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * value = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
1999-04-08 02:10:10 +08:00
2002-10-24 04:26:28 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . tmp_var = * value ;
2002-10-19 05:19:27 +08:00
if ( ! EG ( free_op1 ) ) {
2002-10-24 04:26:28 +08:00
zval_copy_ctor ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var ) ;
2002-10-19 05:19:27 +08:00
}
NEXT_OPCODE ( ) ;
}
1999-04-08 02:10:10 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_ext_stmt_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
if ( ! EG ( no_extensions ) ) {
zend_llist_apply_with_argument ( & zend_extensions , ( llist_apply_with_arg_func_t ) zend_extension_statement_handler , op_array TSRMLS_CC ) ;
}
NEXT_OPCODE ( ) ;
}
1999-04-08 02:10:10 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_ext_fcall_begin_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
if ( ! EG ( no_extensions ) ) {
zend_llist_apply_with_argument ( & zend_extensions , ( llist_apply_with_arg_func_t ) zend_extension_fcall_begin_handler , op_array TSRMLS_CC ) ;
}
NEXT_OPCODE ( ) ;
}
1999-04-08 02:10:10 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_ext_fcall_end_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
if ( ! EG ( no_extensions ) ) {
zend_llist_apply_with_argument ( & zend_extensions , ( llist_apply_with_arg_func_t ) zend_extension_fcall_end_handler , op_array TSRMLS_CC ) ;
}
NEXT_OPCODE ( ) ;
}
2001-08-07 11:17:33 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_declare_class_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-03-05 19:14:44 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . EA . class_entry = do_bind_class ( EX ( opline ) , EG ( function_table ) , EG ( class_table ) TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2002-10-17 02:29:41 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_declare_inherited_class_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-03-05 19:14:44 +08:00
EX_T ( EX ( opline ) - > result . u . var ) . EA . class_entry = do_bind_inherited_class ( EX ( opline ) , EG ( function_table ) , EG ( class_table ) , EX_T ( EX ( opline ) - > extended_value ) . EA . class_entry TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2002-02-05 03:29:56 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_declare_function_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
do_bind_function ( EX ( opline ) , EG ( function_table ) , EG ( class_table ) , 0 ) ;
NEXT_OPCODE ( ) ;
}
2002-02-05 03:29:56 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_ticks_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
if ( + + EG ( ticks_count ) > = EX ( opline ) - > op1 . u . constant . value . lval ) {
EG ( ticks_count ) = 0 ;
if ( zend_ticks_function ) {
zend_ticks_function ( EX ( opline ) - > op1 . u . constant . value . lval ) ;
}
}
NEXT_OPCODE ( ) ;
}
1999-04-08 02:10:10 +08:00
2003-02-10 19:49:21 +08:00
2003-01-15 05:29:23 +08:00
int zend_instanceof_handler ( ZEND_OPCODE_HANDLER_ARGS )
2002-10-19 05:19:27 +08:00
{
zval * expr = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2003-03-05 19:14:44 +08:00
zend_bool result ;
if ( Z_TYPE_P ( expr ) = = IS_OBJECT ) {
result = instanceof_function ( Z_OBJCE_P ( expr ) , EX_T ( EX ( opline ) - > op2 . u . var ) . EA . class_entry TSRMLS_CC ) ;
} else {
result = 0 ;
}
ZVAL_BOOL ( & EX_T ( EX ( opline ) - > result . u . var ) . tmp_var , result ) ;
2002-10-19 05:19:27 +08:00
FREE_OP ( EX ( Ts ) , & EX ( opline ) - > op1 , EG ( free_op1 ) ) ;
NEXT_OPCODE ( ) ;
}
2002-02-05 03:29:56 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_ext_nop_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
NEXT_OPCODE ( ) ;
}
2000-11-22 12:24:35 +08:00
2003-02-10 19:49:21 +08:00
2002-10-19 05:19:27 +08:00
int zend_nop_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
NEXT_OPCODE ( ) ;
}
1999-04-08 02:10:10 +08:00
2003-02-21 03:01:53 +08:00
int zend_start_namespace_handler ( ZEND_OPCODE_HANDLER_ARGS )
2003-02-16 19:12:43 +08:00
{
2003-02-21 03:01:53 +08:00
zval * namespace_name ;
2003-02-16 19:12:43 +08:00
zend_namespace * * pns ;
2003-02-21 03:01:53 +08:00
if ( EX ( opline ) - > op1 . op_type ! = IS_UNUSED ) {
namespace_name = get_zval_ptr ( & EX ( opline ) - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
if ( Z_TYPE_P ( namespace_name ) ! = IS_STRING ) {
zend_error ( E_ERROR , " Internal error: Invalid type in namespace definition - %d " , Z_TYPE_P ( namespace_name ) ) ;
}
2003-02-16 19:12:43 +08:00
2003-04-02 03:37:04 +08:00
if ( zend_hash_find ( & EG ( global_namespace_ptr ) - > class_table , Z_STRVAL_P ( namespace_name ) , Z_STRLEN_P ( namespace_name ) + 1 , ( void * * ) & pns ) ! = SUCCESS | | ( * pns ) - > type ! = ZEND_USER_NAMESPACE ) {
2003-02-21 03:01:53 +08:00
zend_error ( E_ERROR , " Internal error: Cannot locate namespace '%s' " , Z_STRVAL_P ( namespace_name ) ) ;
}
} else {
pns = & EG ( global_namespace_ptr ) ;
2003-02-16 19:12:43 +08:00
}
2003-02-21 03:01:53 +08:00
if ( EG ( active_namespace ) ! = * pns ) {
zend_switch_namespace ( * pns TSRMLS_CC ) ;
2003-02-16 19:12:43 +08:00
}
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2003-03-05 19:14:44 +08:00
int zend_add_interface_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_class_entry * ce = EX_T ( EX ( opline ) - > op1 . u . var ) . EA . class_entry ;
zend_class_entry * iface = EX_T ( EX ( opline ) - > op2 . u . var ) . EA . class_entry ;
if ( ! ( iface - > ce_flags & ZEND_ACC_INTERFACE ) ) {
zend_error ( E_ERROR , " %s cannot implement %s - it is not an interface " , ce - > name , iface - > name ) ;
}
ce - > interfaces [ EX ( opline ) - > extended_value ] = iface ;
zend_do_implement_interface ( ce , iface ) ;
NEXT_OPCODE ( ) ;
}
2003-03-06 22:31:17 +08:00
2003-03-06 22:42:36 +08:00
int zend_verify_instanceof_handler ( ZEND_OPCODE_HANDLER_ARGS )
2003-03-06 22:31:17 +08:00
{
zval * arg = get_zval_ptr ( & EX ( opline ) - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
zend_class_entry * ce = EX_T ( EX ( opline ) - > op1 . u . var ) . EA . class_entry ;
if ( ( Z_TYPE_P ( arg ) ! = IS_OBJECT )
| | ! instanceof_function ( Z_OBJCE_P ( arg ) , ce TSRMLS_CC ) ) {
char * error_msg ;
if ( ce - > ce_flags & ZEND_ACC_INTERFACE ) {
error_msg = " implement interface " ;
} else {
error_msg = " be an instance of " ;
}
zend_error ( E_ERROR , " Argument %d must %s %s " , EX ( opline ) - > extended_value , error_msg , ce - > name ) ;
}
NEXT_OPCODE ( ) ;
}
2003-05-05 03:24:24 +08:00
# define MAX_ABSTRACT_INFO_CNT 3
# define MAX_ABSTRACT_INFO_FMT "%s%s%s%s"
# define DISPLAY_ABSTRACT_FN(idx) \
ai . afn [ idx ] ? ZEND_FN_SCOPE_NAME ( ai . afn [ idx ] ) : " " , \
ai . afn [ idx ] ? " :: " : " " , \
ai . afn [ idx ] ? ai . afn [ idx ] - > common . function_name : " " , \
ai . afn [ idx ] & & ai . afn [ idx + 1 ] ? " , " : ( ai . afn [ idx ] & & ai . cnt > = MAX_ABSTRACT_INFO_CNT ? " , ... " : " " )
typedef struct _zend_abstract_info {
zend_function * afn [ MAX_ABSTRACT_INFO_CNT + 1 ] ;
int cnt ;
} zend_abstract_info ;
int zend_verify_abstract_class_function ( zend_function * fn , zend_abstract_info * ai TSRMLS_DC )
{
if ( fn - > common . fn_flags & ZEND_ACC_ABSTRACT ) {
if ( ai - > cnt < MAX_ABSTRACT_INFO_CNT ) {
ai - > afn [ ai - > cnt ] = fn ;
}
ai - > cnt + + ;
}
return 0 ;
}
2003-03-07 06:53:23 +08:00
int zend_verify_abstract_class ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_class_entry * ce = EX_T ( EX ( opline ) - > op1 . u . var ) . EA . class_entry ;
2003-05-05 03:24:24 +08:00
zend_abstract_info ai ;
2003-03-07 06:53:23 +08:00
2003-05-05 03:24:24 +08:00
if ( ( ce - > ce_flags & ZEND_ACC_ABSTRACT ) & & ! ( ce - > ce_flags & ZEND_ACC_ABSTRACT_CLASS ) ) {
memset ( & ai , 0 , sizeof ( ai ) ) ;
zend_hash_apply_with_argument ( & ce - > function_table , ( apply_func_arg_t ) zend_verify_abstract_class_function , & ai TSRMLS_CC ) ;
zend_error ( E_ERROR , " Class %s contains %d abstract methods and must therefore be declared abstract ( " MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT " ) " ,
ce - > name , ai . cnt ,
DISPLAY_ABSTRACT_FN ( 0 ) ,
DISPLAY_ABSTRACT_FN ( 1 ) ,
DISPLAY_ABSTRACT_FN ( 2 )
) ;
2003-03-07 06:53:23 +08:00
}
NEXT_OPCODE ( ) ;
}
2002-10-19 05:19:27 +08:00
void zend_init_opcodes_handlers ( )
{
zend_opcode_handlers [ ZEND_NOP ] = zend_nop_handler ;
zend_opcode_handlers [ ZEND_ADD ] = zend_add_handler ;
zend_opcode_handlers [ ZEND_SUB ] = zend_sub_handler ;
zend_opcode_handlers [ ZEND_MUL ] = zend_mul_handler ;
zend_opcode_handlers [ ZEND_DIV ] = zend_div_handler ;
zend_opcode_handlers [ ZEND_MOD ] = zend_mod_handler ;
zend_opcode_handlers [ ZEND_SL ] = zend_sl_handler ;
zend_opcode_handlers [ ZEND_SR ] = zend_sr_handler ;
zend_opcode_handlers [ ZEND_CONCAT ] = zend_concat_handler ;
zend_opcode_handlers [ ZEND_BW_OR ] = zend_bw_or_handler ;
zend_opcode_handlers [ ZEND_BW_AND ] = zend_bw_and_handler ;
zend_opcode_handlers [ ZEND_BW_XOR ] = zend_bw_xor_handler ;
zend_opcode_handlers [ ZEND_BW_NOT ] = zend_bw_not_handler ;
zend_opcode_handlers [ ZEND_BOOL_NOT ] = zend_bool_not_handler ;
zend_opcode_handlers [ ZEND_BOOL_XOR ] = zend_bool_xor_handler ;
zend_opcode_handlers [ ZEND_IS_IDENTICAL ] = zend_is_identical_handler ;
zend_opcode_handlers [ ZEND_IS_NOT_IDENTICAL ] = zend_is_not_identical_handler ;
zend_opcode_handlers [ ZEND_IS_EQUAL ] = zend_is_equal_handler ;
zend_opcode_handlers [ ZEND_IS_NOT_EQUAL ] = zend_is_not_equal_handler ;
zend_opcode_handlers [ ZEND_IS_SMALLER ] = zend_is_smaller_handler ;
zend_opcode_handlers [ ZEND_IS_SMALLER_OR_EQUAL ] = zend_is_smaller_or_equal_handler ;
zend_opcode_handlers [ ZEND_CAST ] = zend_cast_handler ;
zend_opcode_handlers [ ZEND_QM_ASSIGN ] = zend_qm_assign_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_ADD ] = zend_assign_add_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_SUB ] = zend_assign_sub_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_MUL ] = zend_assign_mul_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_DIV ] = zend_assign_div_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_MOD ] = zend_assign_mod_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_SL ] = zend_assign_sl_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_SR ] = zend_assign_sr_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_CONCAT ] = zend_assign_concat_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_BW_OR ] = zend_assign_bw_or_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_BW_AND ] = zend_assign_bw_and_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_BW_XOR ] = zend_assign_bw_xor_handler ;
zend_opcode_handlers [ ZEND_PRE_INC ] = zend_pre_inc_handler ;
zend_opcode_handlers [ ZEND_PRE_DEC ] = zend_pre_dec_handler ;
zend_opcode_handlers [ ZEND_POST_INC ] = zend_post_inc_handler ;
zend_opcode_handlers [ ZEND_POST_DEC ] = zend_post_dec_handler ;
zend_opcode_handlers [ ZEND_ASSIGN ] = zend_assign_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_REF ] = zend_assign_ref_handler ;
zend_opcode_handlers [ ZEND_ECHO ] = zend_echo_handler ;
zend_opcode_handlers [ ZEND_PRINT ] = zend_print_handler ;
zend_opcode_handlers [ ZEND_JMP ] = zend_jmp_handler ;
zend_opcode_handlers [ ZEND_JMPZ ] = zend_jmpz_handler ;
zend_opcode_handlers [ ZEND_JMPNZ ] = zend_jmpnz_handler ;
zend_opcode_handlers [ ZEND_JMPZNZ ] = zend_jmpznz_handler ;
zend_opcode_handlers [ ZEND_JMPZ_EX ] = zend_jmpz_ex_handler ;
zend_opcode_handlers [ ZEND_JMPNZ_EX ] = zend_jmpnz_ex_handler ;
zend_opcode_handlers [ ZEND_CASE ] = zend_case_handler ;
zend_opcode_handlers [ ZEND_SWITCH_FREE ] = zend_switch_free_handler ;
zend_opcode_handlers [ ZEND_BRK ] = zend_brk_handler ;
zend_opcode_handlers [ ZEND_CONT ] = zend_cont_handler ;
zend_opcode_handlers [ ZEND_BOOL ] = zend_bool_handler ;
zend_opcode_handlers [ ZEND_INIT_STRING ] = zend_init_string_handler ;
zend_opcode_handlers [ ZEND_ADD_CHAR ] = zend_add_char_handler ;
zend_opcode_handlers [ ZEND_ADD_STRING ] = zend_add_string_handler ;
zend_opcode_handlers [ ZEND_ADD_VAR ] = zend_add_var_handler ;
zend_opcode_handlers [ ZEND_BEGIN_SILENCE ] = zend_begin_silence_handler ;
zend_opcode_handlers [ ZEND_END_SILENCE ] = zend_end_silence_handler ;
zend_opcode_handlers [ ZEND_INIT_FCALL_BY_NAME ] = zend_init_fcall_by_name_handler ;
zend_opcode_handlers [ ZEND_DO_FCALL ] = zend_do_fcall_handler ;
zend_opcode_handlers [ ZEND_DO_FCALL_BY_NAME ] = zend_do_fcall_by_name_handler ;
zend_opcode_handlers [ ZEND_RETURN ] = zend_return_handler ;
zend_opcode_handlers [ ZEND_RECV ] = zend_recv_handler ;
zend_opcode_handlers [ ZEND_RECV_INIT ] = zend_recv_init_handler ;
zend_opcode_handlers [ ZEND_SEND_VAL ] = zend_send_val_handler ;
zend_opcode_handlers [ ZEND_SEND_VAR ] = zend_send_var_handler ;
zend_opcode_handlers [ ZEND_SEND_REF ] = zend_send_ref_handler ;
zend_opcode_handlers [ ZEND_NEW ] = zend_new_handler ;
zend_opcode_handlers [ ZEND_JMP_NO_CTOR ] = zend_jmp_no_ctor_handler ;
zend_opcode_handlers [ ZEND_FREE ] = zend_free_handler ;
zend_opcode_handlers [ ZEND_INIT_ARRAY ] = zend_init_array_handler ;
zend_opcode_handlers [ ZEND_ADD_ARRAY_ELEMENT ] = zend_add_array_element_handler ;
zend_opcode_handlers [ ZEND_INCLUDE_OR_EVAL ] = zend_include_or_eval_handler ;
zend_opcode_handlers [ ZEND_UNSET_VAR ] = zend_unset_var_handler ;
zend_opcode_handlers [ ZEND_UNSET_DIM_OBJ ] = zend_unset_dim_obj_handler ;
zend_opcode_handlers [ ZEND_FE_RESET ] = zend_fe_reset_handler ;
zend_opcode_handlers [ ZEND_FE_FETCH ] = zend_fe_fetch_handler ;
zend_opcode_handlers [ ZEND_EXIT ] = zend_exit_handler ;
zend_opcode_handlers [ ZEND_FETCH_R ] = zend_fetch_r_handler ;
zend_opcode_handlers [ ZEND_FETCH_DIM_R ] = zend_fetch_dim_r_handler ;
zend_opcode_handlers [ ZEND_FETCH_OBJ_R ] = zend_fetch_obj_r_handler ;
zend_opcode_handlers [ ZEND_FETCH_W ] = zend_fetch_w_handler ;
zend_opcode_handlers [ ZEND_FETCH_DIM_W ] = zend_fetch_dim_w_handler ;
zend_opcode_handlers [ ZEND_FETCH_OBJ_W ] = zend_fetch_obj_w_handler ;
zend_opcode_handlers [ ZEND_FETCH_RW ] = zend_fetch_rw_handler ;
zend_opcode_handlers [ ZEND_FETCH_DIM_RW ] = zend_fetch_dim_rw_handler ;
zend_opcode_handlers [ ZEND_FETCH_OBJ_RW ] = zend_fetch_obj_rw_handler ;
zend_opcode_handlers [ ZEND_FETCH_IS ] = zend_fetch_is_handler ;
zend_opcode_handlers [ ZEND_FETCH_DIM_IS ] = zend_fetch_dim_is_handler ;
zend_opcode_handlers [ ZEND_FETCH_OBJ_IS ] = zend_fetch_obj_is_handler ;
zend_opcode_handlers [ ZEND_FETCH_FUNC_ARG ] = zend_fetch_func_arg_handler ;
zend_opcode_handlers [ ZEND_FETCH_DIM_FUNC_ARG ] = zend_fetch_dim_func_arg_handler ;
zend_opcode_handlers [ ZEND_FETCH_OBJ_FUNC_ARG ] = zend_fetch_obj_func_arg_handler ;
zend_opcode_handlers [ ZEND_FETCH_UNSET ] = zend_fetch_unset_handler ;
zend_opcode_handlers [ ZEND_FETCH_DIM_UNSET ] = zend_fetch_dim_unset_handler ;
zend_opcode_handlers [ ZEND_FETCH_OBJ_UNSET ] = zend_fetch_obj_unset_handler ;
zend_opcode_handlers [ ZEND_FETCH_DIM_TMP_VAR ] = zend_fetch_dim_tmp_var_handler ;
zend_opcode_handlers [ ZEND_FETCH_CONSTANT ] = zend_fetch_constant_handler ;
zend_opcode_handlers [ ZEND_EXT_STMT ] = zend_ext_stmt_handler ;
zend_opcode_handlers [ ZEND_EXT_FCALL_BEGIN ] = zend_ext_fcall_begin_handler ;
zend_opcode_handlers [ ZEND_EXT_FCALL_END ] = zend_ext_fcall_end_handler ;
zend_opcode_handlers [ ZEND_EXT_NOP ] = zend_ext_nop_handler ;
zend_opcode_handlers [ ZEND_TICKS ] = zend_ticks_handler ;
zend_opcode_handlers [ ZEND_SEND_VAR_NO_REF ] = zend_send_var_no_ref_handler ;
zend_opcode_handlers [ ZEND_CATCH ] = zend_catch_handler ;
zend_opcode_handlers [ ZEND_THROW ] = zend_throw_handler ;
zend_opcode_handlers [ ZEND_FETCH_CLASS ] = zend_fetch_class_handler ;
zend_opcode_handlers [ ZEND_CLONE ] = zend_clone_handler ;
zend_opcode_handlers [ ZEND_INIT_CTOR_CALL ] = zend_init_ctor_call_handler ;
zend_opcode_handlers [ ZEND_INIT_METHOD_CALL ] = zend_init_method_call_handler ;
zend_opcode_handlers [ ZEND_INIT_STATIC_METHOD_CALL ] = zend_init_static_method_call_handler ;
zend_opcode_handlers [ ZEND_ISSET_ISEMPTY_VAR ] = zend_isset_isempty_var_handler ;
zend_opcode_handlers [ ZEND_ISSET_ISEMPTY_DIM_OBJ ] = zend_isset_isempty_dim_obj_handler ;
zend_opcode_handlers [ ZEND_IMPORT_FUNCTION ] = zend_import_function_handler ;
zend_opcode_handlers [ ZEND_IMPORT_CLASS ] = zend_import_class_handler ;
zend_opcode_handlers [ ZEND_IMPORT_CONST ] = zend_import_const_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_ADD_OBJ ] = zend_assign_add_obj_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_SUB_OBJ ] = zend_assign_sub_obj_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_MUL_OBJ ] = zend_assign_mul_obj_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_DIV_OBJ ] = zend_assign_div_obj_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_MOD_OBJ ] = zend_assign_mod_obj_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_SL_OBJ ] = zend_assign_sl_obj_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_SR_OBJ ] = zend_assign_sr_obj_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_CONCAT_OBJ ] = zend_assign_concat_obj_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_BW_OR_OBJ ] = zend_assign_bw_or_obj_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_BW_AND_OBJ ] = zend_assign_bw_and_obj_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_BW_XOR_OBJ ] = zend_assign_bw_xor_obj_handler ;
zend_opcode_handlers [ ZEND_PRE_INC_OBJ ] = zend_pre_inc_obj_handler ;
zend_opcode_handlers [ ZEND_PRE_DEC_OBJ ] = zend_pre_dec_obj_handler ;
zend_opcode_handlers [ ZEND_POST_INC_OBJ ] = zend_post_inc_obj_handler ;
zend_opcode_handlers [ ZEND_POST_DEC_OBJ ] = zend_post_dec_obj_handler ;
zend_opcode_handlers [ ZEND_ASSIGN_OBJ ] = zend_assign_obj_handler ;
2003-01-27 23:13:01 +08:00
zend_opcode_handlers [ ZEND_OP_DATA ] = NULL ;
2002-10-19 05:19:27 +08:00
2003-01-15 05:29:23 +08:00
zend_opcode_handlers [ ZEND_INSTANCEOF ] = zend_instanceof_handler ;
2002-10-19 05:19:27 +08:00
zend_opcode_handlers [ ZEND_DECLARE_CLASS ] = zend_declare_class_handler ;
zend_opcode_handlers [ ZEND_DECLARE_INHERITED_CLASS ] = zend_declare_inherited_class_handler ;
zend_opcode_handlers [ ZEND_DECLARE_FUNCTION ] = zend_declare_function_handler ;
2002-11-21 02:00:23 +08:00
zend_opcode_handlers [ ZEND_RAISE_ABSTRACT_ERROR ] = zend_raise_abstract_error_handler ;
2003-02-21 03:01:53 +08:00
zend_opcode_handlers [ ZEND_START_NAMESPACE ] = zend_start_namespace_handler ;
2003-03-05 19:14:44 +08:00
zend_opcode_handlers [ ZEND_ADD_INTERFACE ] = zend_add_interface_handler ;
2003-03-06 22:42:36 +08:00
zend_opcode_handlers [ ZEND_VERIFY_INSTANCEOF ] = zend_verify_instanceof_handler ;
2003-03-07 06:53:23 +08:00
zend_opcode_handlers [ ZEND_VERIFY_ABSTRACT_CLASS ] = zend_verify_abstract_class ;
1999-04-08 02:10:10 +08:00
}
2003-02-01 09:49:15 +08:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* indent - tabs - mode : t
* End :
*/