1999-04-08 02:10:10 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Zend Engine |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2004-01-09 01:33:29 +08:00
| Copyright ( c ) 1998 - 2004 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 |
2003-06-11 04:04:29 +08:00
| available through the world - wide - web at the following url : |
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"
2002-11-20 01:51:30 +08:00
# include "zend_ini.h"
2004-02-12 18:38:14 +08:00
# include "zend_exceptions.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
2003-08-19 07:11:58 +08:00
/* former zend_execute_locks.h */
static inline void zend_pzval_lock_func ( zval * z )
{
z - > refcount + + ;
}
static inline void zend_pzval_unlock_func ( zval * z TSRMLS_DC )
{
z - > refcount - - ;
if ( ! z - > refcount ) {
z - > refcount = 1 ;
z - > is_ref = 0 ;
EG ( garbage ) [ EG ( garbage_ptr ) + + ] = z ;
}
}
static inline void zend_clean_garbage ( TSRMLS_D )
{
while ( EG ( garbage_ptr ) ) {
zval_ptr_dtor ( & EG ( garbage ) [ - - EG ( garbage_ptr ) ] ) ;
}
}
# define PZVAL_UNLOCK(z) zend_pzval_unlock_func(z TSRMLS_CC)
# define PZVAL_LOCK(z) zend_pzval_lock_func(z)
2004-02-12 00:28:46 +08:00
# define RETURN_VALUE_UNUSED(pzn) (((pzn)->u.EA.type & EXT_TYPE_UNUSED))
# define SELECTIVE_PZVAL_LOCK(pzv, pzn) if (!RETURN_VALUE_UNUSED(pzn)) { PZVAL_LOCK(pzv); }
2003-08-19 07:11:58 +08:00
/* End of zend_execute_locks.h */
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 {
2003-12-14 20:32:02 +08:00
temp_variable * T = & T ( node - > u . var ) ;
2004-01-19 20:22:02 +08:00
zval * str = T - > str_offset . str ;
2003-12-14 20:32:02 +08:00
/* string offset */
2002-10-24 04:26:28 +08:00
* should_free = & T ( node - > u . var ) . tmp_var ;
1999-04-08 02:10:10 +08:00
2004-01-19 20:22:02 +08:00
if ( T - > str_offset . str - > type ! = IS_STRING
| | ( ( int ) T - > str_offset . offset < 0 )
| | ( T - > str_offset . str - > value . str . len < = T - > str_offset . offset ) ) {
zend_error ( E_NOTICE , " Uninitialized string offset: %d " , T - > str_offset . offset ) ;
2003-12-14 20:32:02 +08:00
T - > tmp_var . value . str . val = empty_string ;
T - > tmp_var . value . str . len = 0 ;
} else {
2004-01-19 20:22:02 +08:00
char c = str - > value . str . val [ T - > str_offset . offset ] ;
2003-12-14 20:32:02 +08:00
T - > tmp_var . value . str . val = estrndup ( & c , 1 ) ;
T - > tmp_var . value . str . len = 1 ;
1999-04-08 02:10:10 +08:00
}
2003-12-14 20:32:02 +08:00
PZVAL_UNLOCK ( str ) ;
T - > tmp_var . refcount = 1 ;
T - > tmp_var . is_ref = 1 ;
T - > tmp_var . type = IS_STRING ;
return & T - > tmp_var ;
1999-04-08 02:10:10 +08:00
}
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 ) ;
2003-12-14 20:32:02 +08:00
} else {
/* string offset */
2004-01-19 20:22:02 +08:00
PZVAL_UNLOCK ( T ( node - > u . var ) . 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
}
}
2003-10-05 15:52:28 +08:00
static inline void zend_fetch_property_address_inner ( zval * object , znode * op2 , znode * result , 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 ) ;
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 ;
}
2003-10-05 15:52:28 +08:00
if ( Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ) {
2004-01-07 08:24:58 +08:00
zval * * ptr_ptr = Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ( object , prop_ptr TSRMLS_CC ) ;
if ( NULL = = ptr_ptr ) {
zend_error ( E_ERROR , " Cannot access undefined property for object with overloaded property access " ) ;
}
T ( result - > u . var ) . var . ptr_ptr = ptr_ptr ;
2003-10-05 15:52:28 +08:00
} else if ( Z_OBJ_HT_P ( object ) - > read_property ) {
2004-03-22 02:07:27 +08:00
T ( result - > u . var ) . var . ptr = Z_OBJ_HT_P ( object ) - > read_property ( object , prop_ptr , BP_VAR_W TSRMLS_CC ) ;
2003-10-05 15:52:28 +08:00
T ( result - > u . var ) . var . ptr_ptr = & T ( result - > u . var ) . var . ptr ;
} else {
2002-03-10 21:42:37 +08:00
zend_error ( E_WARNING , " This object doesn't support property references " ) ;
2003-10-05 15:52:28 +08:00
T ( result - > u . var ) . var . ptr_ptr = & EG ( error_zval_ptr ) ;
2002-03-10 21:42:37 +08:00
}
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
}
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 ) {
2003-11-30 01:33:25 +08:00
temp_variable * T = & T ( opline - > op1 . u . var ) ;
/* perform the equivalent of equivalent of a
* quick & silent get_zval_ptr , and FREE_OP
*/
2004-01-19 20:22:02 +08:00
PZVAL_UNLOCK ( T - > str_offset . str ) ;
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 ) ;
}
2003-12-01 20:35:46 +08:00
zend_error ( E_STRICT , " Creating default object from empty value " ) ;
2002-03-10 21:42:37 +08:00
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 ) ;
}
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
static inline void zend_verify_arg_type ( zend_function * zf , zend_uint arg_num , zval * arg TSRMLS_DC )
{
zend_arg_info * cur_arg_info ;
if ( ! zf - > common . arg_info
| | arg_num > zf - > common . num_args ) {
return ;
}
cur_arg_info = & zf - > common . arg_info [ arg_num - 1 ] ;
if ( cur_arg_info - > class_name ) {
if ( ! arg ) {
zend_error ( E_ERROR , " Argument %d must be an object of class %s " , arg_num , cur_arg_info - > class_name ) ;
}
switch ( Z_TYPE_P ( arg ) ) {
case IS_NULL :
if ( ! cur_arg_info - > allow_null ) {
zend_error ( E_ERROR , " Argument %d must not be null " , arg_num ) ;
}
break ;
case IS_OBJECT : {
zend_class_entry * ce = zend_fetch_class ( cur_arg_info - > class_name , cur_arg_info - > class_name_len , ZEND_FETCH_CLASS_AUTO TSRMLS_CC ) ;
if ( ! 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 " , arg_num , error_msg , ce - > name ) ;
}
}
break ;
default :
zend_error ( E_ERROR , " Argument %d must be an object of class %s " , arg_num , cur_arg_info - > class_name ) ;
break ;
}
}
}
2003-07-07 17:00:36 +08:00
static inline void zend_assign_to_object ( znode * result , zval * * object_ptr , znode * op2 , znode * value_op , temp_variable * Ts , int opcode TSRMLS_DC )
2002-03-10 21:42:37 +08:00
{
zval * object ;
2004-02-11 23:56:13 +08:00
zval * property_name = 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-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 */
2003-01-29 16:55:12 +08:00
/* separate our value if necessary */
2004-03-24 18:55:04 +08:00
if ( EG ( ze1_compatibility_mode ) & & Z_TYPE_P ( value ) = = IS_OBJECT ) {
zval * orig_value = value ;
ALLOC_ZVAL ( value ) ;
* value = * orig_value ;
value - > is_ref = 0 ;
value - > refcount = 0 ;
2004-03-28 22:57:29 +08:00
if ( Z_OBJ_HANDLER_P ( value , clone_obj ) = = NULL ) {
2004-03-24 18:55:04 +08:00
zend_error ( E_ERROR , " Trying to clone an uncloneable object of class %s " , Z_OBJCE_P ( orig_value ) - > name ) ;
}
2004-03-29 23:20:50 +08:00
zend_error ( E_STRICT , " Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode' " , Z_OBJCE_P ( orig_value ) - > name ) ;
2004-03-28 22:57:29 +08:00
value - > value . obj = Z_OBJ_HANDLER_P ( orig_value , clone_obj ) ( orig_value TSRMLS_CC ) ;
2004-03-24 18:55:04 +08:00
} else if ( value_op - > op_type = = IS_TMP_VAR ) {
2003-01-29 16:55:12 +08:00
zval * orig_value = value ;
ALLOC_ZVAL ( value ) ;
* value = * orig_value ;
value - > is_ref = 0 ;
value - > refcount = 0 ;
2004-02-12 03:12:16 +08:00
} else if ( value_op - > op_type = = IS_CONST ) {
zval * orig_value = value ;
ALLOC_ZVAL ( value ) ;
* value = * orig_value ;
value - > is_ref = 0 ;
value - > refcount = 0 ;
zval_copy_ctor ( value ) ;
2003-01-29 16:55:12 +08:00
}
2004-03-24 18:55:04 +08:00
2004-02-12 03:12:16 +08:00
value - > refcount + + ;
2003-07-07 17:00:36 +08:00
if ( opcode = = ZEND_ASSIGN_OBJ ) {
2004-02-11 23:56:13 +08:00
zval tmp ;
switch ( op2 - > op_type ) {
case IS_CONST :
/* already a constant string */
break ;
case IS_VAR :
tmp = * property_name ;
zval_copy_ctor ( & tmp ) ;
convert_to_string ( & tmp ) ;
property_name = & tmp ;
break ;
case IS_TMP_VAR :
convert_to_string ( property_name ) ;
break ;
}
Z_OBJ_HT_P ( object ) - > write_property ( object , property_name , value TSRMLS_CC ) ;
if ( property_name = = & tmp ) {
zval_dtor ( property_name ) ;
}
2003-07-07 17:00:36 +08:00
} else {
2004-02-11 23:56:13 +08:00
/* Note: property_name in this case is really the array index! */
2003-07-31 01:12:06 +08:00
if ( ! Z_OBJ_HT_P ( object ) - > write_dimension ) {
zend_error ( E_ERROR , " Cannot use object as array " ) ;
}
2004-02-11 23:56:13 +08:00
Z_OBJ_HT_P ( object ) - > write_dimension ( object , property_name , value TSRMLS_CC ) ;
2002-03-10 21:42:37 +08:00
}
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
if ( result ) {
2002-10-24 04:26:28 +08:00
T ( result - > u . var ) . var . ptr = value ;
2004-02-04 19:47:54 +08:00
T ( result - > u . var ) . var . ptr_ptr = NULL ; /* see if we can remove this */
2002-03-10 21:42:37 +08:00
SELECTIVE_PZVAL_LOCK ( value , result ) ;
}
2004-03-18 22:03:58 +08:00
zval_ptr_dtor ( & value ) ;
2002-03-10 21:42:37 +08:00
}
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 ) {
2003-12-14 20:32:02 +08:00
temp_variable * T = & T ( op1 - > u . var ) ;
1999-04-08 02:10:10 +08:00
2004-01-19 20:22:02 +08:00
if ( T - > str_offset . str - > type = = IS_STRING ) do {
2003-12-14 20:32:02 +08:00
zval tmp ;
zval * final_value = value ;
1999-04-08 02:10:10 +08:00
2004-01-19 20:22:02 +08:00
if ( ( ( int ) T - > str_offset . offset < 0 ) ) {
zend_error ( E_WARNING , " Illegal string offset: %d " , T - > str_offset . offset ) ;
2003-12-14 20:32:02 +08:00
break ;
}
2004-01-19 20:22:02 +08:00
if ( T - > str_offset . offset > = T - > str_offset . str - > value . str . len ) {
2003-12-14 20:32:02 +08:00
zend_uint i ;
2001-06-27 23:40:49 +08:00
2004-01-19 20:22:02 +08:00
if ( T - > str_offset . str - > value . str . len = = 0 ) {
STR_FREE ( T - > str_offset . str - > value . str . val ) ;
T - > str_offset . str - > value . str . val = ( char * ) emalloc ( T - > str_offset . offset + 1 + 1 ) ;
2003-12-14 20:32:02 +08:00
} else {
2004-01-19 20:22:02 +08:00
T - > str_offset . str - > value . str . val = ( char * ) erealloc ( T - > str_offset . str - > value . str . val , T - > str_offset . offset + 1 + 1 ) ;
2003-12-14 20:32:02 +08:00
}
2004-01-19 20:22:02 +08:00
for ( i = T - > str_offset . str - > value . str . len ; i < T - > str_offset . offset ; i + + ) {
T - > str_offset . str - > value . str . val [ i ] = ' ' ;
2003-12-14 20:32:02 +08:00
}
2004-01-19 20:22:02 +08:00
T - > str_offset . str - > value . str . val [ T - > str_offset . offset + 1 ] = 0 ;
T - > str_offset . str - > value . str . len = T - > str_offset . offset + 1 ;
2003-12-14 20:32:02 +08:00
}
1999-04-08 02:10:10 +08:00
2003-12-14 20:32:02 +08:00
if ( value - > type ! = IS_STRING ) {
tmp = * value ;
if ( op2 & & op2 - > op_type = = IS_VAR ) {
zval_copy_ctor ( & tmp ) ;
}
convert_to_string ( & tmp ) ;
final_value = & tmp ;
}
2004-01-19 20:22:02 +08:00
T - > str_offset . str - > value . str . val [ T - > str_offset . offset ] = final_value - > value . str . val [ 0 ] ;
2003-12-14 20:32:02 +08:00
if ( op2 ) {
if ( op2 - > op_type = = IS_VAR ) {
if ( value = = & T ( op2 - > u . var ) . tmp_var ) {
if ( result - > u . EA . type & EXT_TYPE_UNUSED ) {
/* We are not going to use return value, drop it */
STR_FREE ( value - > value . str . val ) ;
} else {
/* We are going to use return value, make it real zval */
ALLOC_ZVAL ( value ) ;
* value = T ( op2 - > u . var ) . tmp_var ;
value - > is_ref = 0 ;
value - > refcount = 0 ; /* LOCK will increase it */
1999-04-08 02:10:10 +08:00
}
2003-12-14 20:32:02 +08:00
}
} 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-04-08 02:10:10 +08:00
}
2003-12-14 20:32:02 +08:00
}
if ( final_value = = & tmp ) {
zval_dtor ( final_value ) ;
}
/*
* the value of an assignment to a string offset is undefined
2004-01-19 20:22:02 +08:00
T ( result - > u . var ) . var = & T - > str_offset . str ;
2003-12-14 20:32:02 +08:00
*/
} while ( 0 ) ;
2004-01-19 20:22:02 +08:00
/* zval_ptr_dtor(&T->str_offset.str); Nuke this line if it doesn't cause a leak */
2003-12-14 20:32:02 +08:00
T - > tmp_var . type = IS_STRING ;
2003-06-16 23:41:02 +08:00
/* T(result->u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr); */
T ( result - > u . var ) . var . ptr_ptr = & value ;
2002-10-24 04:26:28 +08:00
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 ;
}
2004-03-25 21:03:04 +08:00
2004-03-28 22:57:29 +08:00
if ( Z_TYPE_P ( variable_ptr ) = = IS_OBJECT & & Z_OBJ_HANDLER_P ( variable_ptr , set ) ) {
/* TODO? ze1_compatibility_mode support */
Z_OBJ_HANDLER_P ( variable_ptr , set ) ( variable_ptr_ptr , value TSRMLS_CC ) ;
goto done_setting_var ;
}
2004-03-24 18:55:04 +08:00
if ( EG ( ze1_compatibility_mode ) & & Z_TYPE_P ( value ) = = IS_OBJECT ) {
2004-03-28 22:57:29 +08:00
if ( Z_OBJ_HANDLER_P ( value , clone_obj ) = = NULL ) {
2004-03-24 18:55:04 +08:00
zend_error ( E_ERROR , " Trying to clone an uncloneable object of class %s " , Z_OBJCE_P ( value ) - > name ) ;
} else if ( PZVAL_IS_REF ( variable_ptr ) ) {
if ( variable_ptr ! = value ) {
zend_uint refcount = variable_ptr - > refcount ;
zval garbage ;
if ( type ! = IS_TMP_VAR ) {
value - > refcount + + ;
}
garbage = * variable_ptr ;
* variable_ptr = * value ;
variable_ptr - > refcount = refcount ;
variable_ptr - > is_ref = 1 ;
2004-03-29 23:20:50 +08:00
zend_error ( E_STRICT , " Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode' " , Z_OBJCE_P ( value ) - > name ) ;
2004-03-28 22:57:29 +08:00
variable_ptr - > value . obj = Z_OBJ_HANDLER_P ( value , clone_obj ) ( value TSRMLS_CC ) ;
2004-03-24 18:55:04 +08:00
if ( type ! = IS_TMP_VAR ) {
value - > refcount - - ;
}
zendi_zval_dtor ( garbage ) ;
}
} else {
variable_ptr - > refcount - - ;
if ( variable_ptr - > refcount = = 0 ) {
zendi_zval_dtor ( * variable_ptr ) ;
} else {
ALLOC_ZVAL ( variable_ptr ) ;
* variable_ptr_ptr = variable_ptr ;
}
* variable_ptr = * value ;
INIT_PZVAL ( variable_ptr ) ;
2004-03-29 23:20:50 +08:00
zend_error ( E_STRICT , " Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode' " , Z_OBJCE_P ( value ) - > name ) ;
2004-03-28 22:57:29 +08:00
variable_ptr - > value . obj = Z_OBJ_HANDLER_P ( value , clone_obj ) ( value TSRMLS_CC ) ;
2004-03-24 18:55:04 +08:00
}
} else 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 ;
2004-03-25 21:03:04 +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 ;
2004-03-25 21:03:04 +08:00
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 ;
2004-03-25 21:03:04 +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 ;
2004-03-25 21:03:04 +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
}
2004-03-28 22:57:29 +08:00
done_setting_var :
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-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 ;
2003-05-21 19:48:55 +08:00
zend_bool free_tmp = 0 ;
2002-02-05 03:29:56 +08:00
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 ;
2003-05-21 19:48:55 +08:00
free_tmp = 1 ;
1999-04-08 02:10:10 +08:00
}
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-12-14 20:32:02 +08:00
retval = zend_std_get_static_property ( T ( opline - > op2 . u . var ) . class_entry , Z_STRVAL_P ( varname ) , Z_STRLEN_P ( varname ) , 0 TSRMLS_CC ) ;
2003-02-05 21:35:52 +08:00
} else {
2003-06-30 21:47:12 +08:00
if ( opline - > op2 . u . EA . type = = ZEND_FETCH_GLOBAL & & opline - > op1 . op_type = = IS_VAR ) {
2003-06-30 21:51:48 +08:00
varname - > refcount + + ;
2003-06-30 21:47:12 +08:00
}
2003-02-05 21:35:52 +08:00
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 :
2003-09-05 00:00:01 +08:00
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
2003-05-21 19:48:55 +08:00
if ( free_tmp ) {
1999-04-08 02:10:10 +08:00
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 :
2003-05-23 23:11:15 +08:00
2000-01-04 01:26:24 +08:00
offset_key = dim - > value . str . val ;
offset_key_length = dim - > value . str . len ;
2003-05-23 23:11:15 +08:00
2000-01-04 01:26:24 +08:00
fetch_string_dim :
2003-07-23 00:06:07 +08:00
if ( zend_symtable_find ( ht , offset_key , offset_key_length + 1 , ( void * * ) & retval ) = = FAILURE ) {
2000-01-04 01:26:24 +08:00
switch ( type ) {
2004-02-11 21:58:29 +08:00
case BP_VAR_R :
zend_error ( E_NOTICE , " Undefined index: %s " , offset_key ) ;
2000-01-04 01:26:24 +08:00
/* break missing intentionally */
2004-02-11 21:58:29 +08:00
case BP_VAR_UNSET :
2000-01-04 01:26:24 +08:00
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 + + ;
2003-07-24 20:56:05 +08:00
zend_symtable_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 :
2003-07-23 00:06:07 +08:00
case IS_LONG : {
long index ;
1999-09-09 04:38:08 +08:00
2003-07-23 00:06:07 +08:00
if ( dim - > type = = IS_DOUBLE ) {
index = ( long ) dim - > value . dval ;
} else {
index = dim - > value . lval ;
}
if ( zend_hash_index_find ( ht , index , ( void * * ) & retval ) = = FAILURE ) {
switch ( type ) {
2004-02-11 21:58:29 +08:00
case BP_VAR_R :
2003-08-29 00:41:20 +08:00
zend_error ( E_NOTICE , " Undefined offset: %ld " , index ) ;
2003-07-23 00:06:07 +08:00
/* break missing intentionally */
2004-02-11 21:58:29 +08:00
case BP_VAR_UNSET :
2003-07-23 00:06:07 +08:00
case BP_VAR_IS :
retval = & EG ( uninitialized_zval_ptr ) ;
break ;
case BP_VAR_RW :
2003-08-29 00:41:20 +08:00
zend_error ( E_NOTICE , " Undefined offset: %ld " , index ) ;
2003-07-23 00:06:07 +08:00
/* break missing intentionally */
case BP_VAR_W : {
zval * new_zval = & EG ( uninitialized_zval ) ;
new_zval - > refcount + + ;
zend_hash_index_update ( ht , index , & new_zval , sizeof ( zval * ) , ( void * * ) & retval ) ;
}
break ;
1999-04-08 02:10:10 +08:00
}
}
}
break ;
default :
zend_error ( E_WARNING , " Illegal offset type " ) ;
2004-02-11 21:58:29 +08:00
switch ( type ) {
case BP_VAR_R :
case BP_VAR_IS :
case BP_VAR_UNSET :
retval = & EG ( uninitialized_zval_ptr ) ;
break ;
default :
retval = & EG ( error_zval_ptr ) ;
break ;
1999-04-08 02:10:10 +08:00
}
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 ) {
2003-12-14 20:32:02 +08:00
zend_error ( E_ERROR , " Cannot use string offset as an array " ) ;
2002-11-13 23:13:24 +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 ;
}
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 ;
}
2004-02-11 21:58:29 +08:00
switch ( type ) {
case BP_VAR_R :
case BP_VAR_IS :
case BP_VAR_UNSET :
/* do nothing... */
break ;
default :
SEPARATE_ZVAL_IF_NOT_REF ( container_ptr ) ;
break ;
1999-04-08 02:10:10 +08:00
}
1999-12-31 21:56:59 +08:00
container = * container_ptr ;
2004-01-19 20:22:02 +08:00
T ( result - > u . var ) . str_offset . str = container ;
1999-12-31 21:56:59 +08:00
PZVAL_LOCK ( container ) ;
2004-01-19 20:22:02 +08:00
T ( result - > u . var ) . str_offset . offset = offset - > value . lval ;
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 ;
2003-07-07 18:53:27 +08:00
case IS_OBJECT :
2004-02-09 01:23:20 +08:00
if ( ! Z_OBJ_HT_P ( container ) - > read_dimension ) {
zend_error ( E_ERROR , " Cannot use object as array " ) ;
} else {
zval * dim = get_zval_ptr ( op2 , Ts , & EG ( free_op2 ) , BP_VAR_R ) ;
zval * overloaded_result = Z_OBJ_HT_P ( container ) - > read_dimension ( container , dim , type TSRMLS_CC ) ;
2003-11-25 04:57:54 +08:00
2004-02-09 01:23:20 +08:00
if ( overloaded_result ) {
2004-02-11 23:50:23 +08:00
switch ( type ) {
case BP_VAR_RW :
case BP_VAR_W :
if ( overloaded_result - > type ! = IS_OBJECT
& & ! overloaded_result - > is_ref ) {
zend_error ( E_ERROR , " Objects used as arrays in post/pre increment/decrement must return values by reference " ) ;
}
break ;
2003-12-11 17:52:33 +08:00
}
2004-02-09 01:23:20 +08:00
* retval = & overloaded_result ;
} else {
* retval = & EG ( error_zval_ptr ) ;
2003-07-31 01:12:06 +08:00
}
2004-02-09 01:23:20 +08:00
AI_USE_PTR ( T ( result - > u . var ) . var ) ;
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
SELECTIVE_PZVAL_LOCK ( * * retval , result ) ;
2003-07-07 18:53:27 +08:00
}
break ;
1999-04-08 02:10:10 +08:00
default : {
2003-08-18 02:56:54 +08:00
get_zval_ptr ( op2 , Ts , & EG ( free_op2 ) , BP_VAR_R ) ;
2004-02-11 21:58:29 +08:00
switch ( type ) {
case BP_VAR_UNSET :
zend_error ( E_WARNING , " Cannot unset offset in a non-array variable " ) ;
/* break missing intentionally */
case BP_VAR_R :
case BP_VAR_IS :
* retval = & EG ( uninitialized_zval_ptr ) ;
break ;
default :
* retval = & EG ( error_zval_ptr ) ;
break ;
1999-04-08 02:10:10 +08:00
}
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 ) {
2003-08-18 02:56:54 +08:00
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 ;
}
2003-10-05 15:52:28 +08:00
zend_fetch_property_address_inner ( container , op2 , result , 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 ;
2004-03-25 21:03:04 +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
2004-03-25 21:03:04 +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 ;
2004-03-25 21:03:04 +08:00
2002-02-07 22:08:43 +08:00
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 */
2004-03-22 02:07:27 +08:00
* retval = Z_OBJ_HT_P ( container ) - > read_property ( container , offset , type TSRMLS_CC ) ;
2002-02-07 22:08:43 +08:00
if ( offset = = & tmp ) {
zval_dtor ( offset ) ;
}
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
2004-02-12 00:28:46 +08:00
if ( RETURN_VALUE_UNUSED ( result ) & & ( ( * retval ) - > refcount = = 0 ) ) {
zval_dtor ( * retval ) ;
FREE_ZVAL ( * retval ) ;
return ; /* no need for locking */
}
2001-05-03 03:51:33 +08:00
}
2002-02-07 22:08:43 +08:00
SELECTIVE_PZVAL_LOCK ( * retval , result ) ;
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 */
2003-10-05 15:52:28 +08:00
if ( Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ) {
zval * * zptr = Z_OBJ_HT_P ( object ) - > get_property_ptr_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 ) {
2004-03-22 02:07:27 +08:00
zval * z = Z_OBJ_HT_P ( object ) - > read_property ( object , property , BP_VAR_RW TSRMLS_CC ) ;
2004-02-10 17:29:42 +08:00
if ( z - > type = = IS_OBJECT & & Z_OBJ_HT_P ( z ) - > get ) {
zval * value = Z_OBJ_HT_P ( z ) - > get ( z TSRMLS_CC ) ;
if ( z - > refcount = = 0 ) {
zval_dtor ( z ) ;
FREE_ZVAL ( z ) ;
}
z = value ;
}
2004-02-10 22:52:14 +08:00
z - > refcount + + ;
2002-03-10 21:42:37 +08:00
SEPARATE_ZVAL_IF_NOT_REF ( & z ) ;
incdec_op ( z ) ;
2004-02-10 17:29:42 +08:00
* retval = z ;
2002-03-10 21:42:37 +08:00
Z_OBJ_HT_P ( object ) - > write_property ( object , property , z TSRMLS_CC ) ;
2004-02-10 17:29:42 +08:00
SELECTIVE_PZVAL_LOCK ( * retval , result ) ;
2004-02-10 22:52:14 +08:00
zval_ptr_dtor ( & z ) ;
2002-03-10 21:42:37 +08:00
}
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 */
2003-10-05 15:52:28 +08:00
if ( Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ) {
zval * * zptr = Z_OBJ_HT_P ( object ) - > get_property_ptr_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 ) {
2004-03-22 02:07:27 +08:00
zval * z = Z_OBJ_HT_P ( object ) - > read_property ( object , property , BP_VAR_RW TSRMLS_CC ) ;
2004-02-10 17:29:42 +08:00
if ( z - > type = = IS_OBJECT & & Z_OBJ_HT_P ( object ) - > get ) {
zval * value = Z_OBJ_HT_P ( object ) - > get ( z TSRMLS_CC ) ;
if ( z - > refcount = = 0 ) {
zval_dtor ( z ) ;
FREE_ZVAL ( z ) ;
}
z = value ;
}
2002-03-10 21:42:37 +08:00
* retval = * z ;
zendi_zval_copy_ctor ( * retval ) ;
incdec_op ( z ) ;
Z_OBJ_HT_P ( object ) - > write_property ( object , property , z TSRMLS_CC ) ;
2004-02-10 17:29:42 +08:00
if ( z - > refcount = = 0 ) {
2002-03-10 21:42:37 +08:00
zval_dtor ( z ) ;
2004-02-10 17:29:42 +08:00
FREE_ZVAL ( z ) ;
2002-03-10 21:42:37 +08:00
}
}
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
2004-02-03 20:17:09 +08:00
# define SET_OPCODE(new_op) \
CHECK_SYMBOL_TABLES ( ) \
EX ( opline ) = new_op ;
2004-02-10 18:07:46 +08:00
# define INC_OPCODE() \
if ( ! EG ( exception ) ) { \
CHECK_SYMBOL_TABLES ( ) \
EX ( opline ) + + ; \
}
2004-02-03 20:17:09 +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 */
2004-02-29 23:04:22 +08:00
ZEND_API 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 ) {
2004-02-03 20:17:09 +08:00
SET_OPCODE ( op_array - > start_op ) ;
2001-07-15 22:08:58 +08:00
} else {
2004-02-03 20:17:09 +08:00
SET_OPCODE ( 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-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 ) ;
2004-02-03 20:17:09 +08:00
if ( EX ( opline ) - > handler ( & execute_data , EX ( opline ) , 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 )
{
2004-02-03 20:17:09 +08:00
add_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
sub_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
mul_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
div_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
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_mod_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
mod_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
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_sl_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
shift_left_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
shift_right_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
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_concat_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
concat_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
is_identical_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
is_not_identical_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
is_equal_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
is_not_equal_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
is_smaller_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
is_smaller_or_equal_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
bitwise_or_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
bitwise_and_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
bitwise_xor_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
boolean_xor_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
bitwise_not_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
boolean_not_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) TSRMLS_CC ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2002-01-04 14:44:19 +08:00
2003-02-10 19:49:21 +08:00
2003-07-08 19:52:21 +08:00
static inline int zend_binary_assign_op_obj_helper ( int ( * binary_op ) ( zval * result , zval * op1 , zval * op2 TSRMLS_DC ) , ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
zend_op * op_data = opline + 1 ;
zval * * object_ptr = get_obj_zval_ptr_ptr ( & opline - > op1 , EX ( Ts ) , BP_VAR_W TSRMLS_CC ) ;
2003-07-08 19:52:21 +08:00
zval * object ;
2004-02-03 20:17:09 +08:00
zval * property = get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
2003-07-08 19:52:21 +08:00
zval * free_value ;
zval * value = get_zval_ptr ( & op_data - > op1 , EX ( Ts ) , & free_value , BP_VAR_R ) ;
zval tmp ;
2004-02-03 20:17:09 +08:00
znode * result = & opline - > result ;
2003-07-08 19:52:21 +08:00
zval * * retval = & EX_T ( result - > u . var ) . var . ptr ;
int have_get_ptr = 0 ;
EX_T ( result - > u . var ) . var . ptr_ptr = NULL ;
make_real_object ( object_ptr TSRMLS_CC ) ;
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 ) ) ;
2004-03-02 18:13:43 +08:00
FREE_OP ( Ts , value , free_value ) ;
2003-07-08 19:52:21 +08:00
* retval = EG ( uninitialized_zval_ptr ) ;
SELECTIVE_PZVAL_LOCK ( * retval , result ) ;
} else {
/* here we are sure we are dealing with an object */
2004-02-03 20:17:09 +08:00
switch ( opline - > op2 . op_type ) {
2003-07-08 19:52:21 +08:00
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 */
2004-02-03 20:17:09 +08:00
if ( opline - > extended_value = = ZEND_ASSIGN_OBJ
2003-10-05 15:52:28 +08:00
& & Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ) {
zval * * zptr = Z_OBJ_HT_P ( object ) - > get_property_ptr_ptr ( object , property TSRMLS_CC ) ;
2003-07-08 19:52:21 +08:00
if ( zptr ! = NULL ) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF ( zptr ) ;
have_get_ptr = 1 ;
binary_op ( * zptr , * zptr , value TSRMLS_CC ) ;
* retval = * zptr ;
SELECTIVE_PZVAL_LOCK ( * retval , result ) ;
}
}
if ( ! have_get_ptr ) {
2003-07-31 01:40:54 +08:00
zval * z ;
2004-02-03 20:17:09 +08:00
switch ( opline - > extended_value ) {
2003-07-31 01:40:54 +08:00
case ZEND_ASSIGN_OBJ :
2004-03-22 02:07:27 +08:00
z = Z_OBJ_HT_P ( object ) - > read_property ( object , property , BP_VAR_RW TSRMLS_CC ) ;
2003-07-31 01:40:54 +08:00
break ;
case ZEND_ASSIGN_DIM :
2004-03-22 02:07:27 +08:00
z = Z_OBJ_HT_P ( object ) - > read_dimension ( object , property , BP_VAR_RW TSRMLS_CC ) ;
2003-07-31 01:40:54 +08:00
break ;
}
2004-02-10 17:29:42 +08:00
if ( z - > type = = IS_OBJECT & & Z_OBJ_HT_P ( z ) - > get ) {
zval * value = Z_OBJ_HT_P ( z ) - > get ( z TSRMLS_CC ) ;
if ( z - > refcount = = 0 ) {
zval_dtor ( z ) ;
FREE_ZVAL ( z ) ;
}
z = value ;
}
2004-02-10 22:52:14 +08:00
z - > refcount + + ;
2003-07-08 19:52:21 +08:00
SEPARATE_ZVAL_IF_NOT_REF ( & z ) ;
binary_op ( z , z , value TSRMLS_CC ) ;
2004-02-03 20:17:09 +08:00
switch ( opline - > extended_value ) {
2003-07-31 01:40:54 +08:00
case ZEND_ASSIGN_OBJ :
Z_OBJ_HT_P ( object ) - > write_property ( object , property , z TSRMLS_CC ) ;
break ;
case ZEND_ASSIGN_DIM :
Z_OBJ_HT_P ( object ) - > write_dimension ( object , property , z TSRMLS_CC ) ;
break ;
}
2003-07-08 19:52:21 +08:00
* retval = z ;
SELECTIVE_PZVAL_LOCK ( * retval , result ) ;
2004-02-10 22:52:14 +08:00
zval_ptr_dtor ( & z ) ;
2003-07-08 19:52:21 +08:00
}
if ( property = = & tmp ) {
zval_dtor ( property ) ;
}
FREE_OP ( Ts , op2 , EG ( free_op2 ) ) ;
2004-03-02 18:13:43 +08:00
FREE_OP ( Ts , value , free_value ) ;
2003-07-08 19:52:21 +08:00
}
/* assign_obj has two opcodes! */
2004-02-03 20:17:09 +08:00
INC_OPCODE ( ) ;
2003-07-08 19:52:21 +08:00
NEXT_OPCODE ( ) ;
}
2003-08-16 05:02:35 +08:00
static inline int zend_binary_assign_op_helper ( int ( * binary_op ) ( zval * result , zval * op1 , zval * op2 TSRMLS_DC ) , ZEND_OPCODE_HANDLER_ARGS )
2003-07-16 16:57:08 +08:00
{
zval * * var_ptr ;
2003-07-31 17:06:11 +08:00
zval * value ;
zend_bool increment_opline = 0 ;
2003-07-16 16:57:08 +08:00
2004-02-03 20:17:09 +08:00
switch ( opline - > extended_value ) {
2003-07-31 01:40:54 +08:00
case ZEND_ASSIGN_OBJ :
2003-07-31 17:06:11 +08:00
return zend_binary_assign_op_obj_helper ( binary_op , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
break ;
case ZEND_ASSIGN_DIM : {
2004-02-03 20:17:09 +08:00
zval * * object_ptr = get_obj_zval_ptr_ptr ( & opline - > op1 , EX ( Ts ) , BP_VAR_W TSRMLS_CC ) ;
2003-07-31 17:06:11 +08:00
2003-12-19 19:22:13 +08:00
( * object_ptr ) - > refcount + + ; /* undo the effect of get_obj_zval_ptr_ptr() */
2003-07-31 17:06:11 +08:00
if ( ( * object_ptr ) - > type = = IS_OBJECT ) {
2003-12-19 19:22:13 +08:00
return zend_binary_assign_op_obj_helper ( binary_op , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
2003-07-31 17:06:11 +08:00
} else {
2004-03-22 05:29:17 +08:00
zend_op * op_data = opline + 1 ;
2003-07-31 17:06:11 +08:00
2004-03-22 05:29:17 +08:00
zend_fetch_dimension_address ( & op_data - > op2 , & opline - > op1 , & opline - > op2 , EX ( Ts ) , BP_VAR_RW TSRMLS_CC ) ;
2003-07-31 17:06:11 +08:00
2004-03-22 05:29:17 +08:00
value = get_zval_ptr ( & op_data - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
var_ptr = get_zval_ptr_ptr ( & op_data - > op2 , EX ( Ts ) , BP_VAR_RW ) ;
2003-07-31 17:06:11 +08:00
EG ( free_op2 ) = 0 ;
increment_opline = 1 ;
}
}
2003-07-31 01:40:54 +08:00
break ;
default :
2004-02-03 20:17:09 +08:00
value = get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
var_ptr = get_zval_ptr_ptr ( & opline - > op1 , EX ( Ts ) , BP_VAR_RW ) ;
2003-07-31 17:06:11 +08:00
EG ( free_op1 ) = 0 ;
2003-07-31 01:40:54 +08:00
/* do nothing */
break ;
2003-07-16 16:57:08 +08:00
}
if ( ! var_ptr ) {
zend_error ( E_ERROR , " Cannot use assign-op operators with overloaded objects nor string offsets " ) ;
}
if ( * var_ptr = = EG ( error_zval_ptr ) ) {
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . var . ptr_ptr = & EG ( uninitialized_zval_ptr ) ;
SELECTIVE_PZVAL_LOCK ( * EX_T ( opline - > result . u . var ) . var . ptr_ptr , & opline - > result ) ;
AI_USE_PTR ( EX_T ( opline - > result . u . var ) . var ) ;
2003-07-16 16:57:08 +08:00
NEXT_OPCODE ( ) ;
}
SEPARATE_ZVAL_IF_NOT_REF ( var_ptr ) ;
2004-03-25 21:03:04 +08:00
if ( Z_TYPE_PP ( var_ptr ) = = IS_OBJECT & & Z_OBJ_HANDLER_PP ( var_ptr , get )
& & Z_OBJ_HANDLER_PP ( var_ptr , set ) ) {
/* proxy object */
2004-03-26 08:26:19 +08:00
zval * objval = Z_OBJ_HANDLER_PP ( var_ptr , get ) ( * var_ptr TSRMLS_CC ) ;
2004-03-25 21:03:04 +08:00
objval - > refcount + + ;
binary_op ( objval , objval , value TSRMLS_CC ) ;
2004-03-26 08:26:19 +08:00
Z_OBJ_HANDLER_PP ( var_ptr , set ) ( var_ptr , objval TSRMLS_CC ) ;
2004-03-25 21:03:04 +08:00
zval_ptr_dtor ( & objval ) ;
} else {
binary_op ( * var_ptr , * var_ptr , value TSRMLS_CC ) ;
}
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . var . ptr_ptr = var_ptr ;
SELECTIVE_PZVAL_LOCK ( * var_ptr , & opline - > result ) ;
FREE_OP ( Ex ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
AI_USE_PTR ( EX_T ( opline - > result . u . var ) . var ) ;
2003-07-16 16:57:08 +08:00
2003-07-31 17:06:11 +08:00
if ( increment_opline ) {
2004-02-03 20:17:09 +08:00
INC_OPCODE ( ) ;
2003-07-31 17:06:11 +08:00
}
2003-07-16 16:57:08 +08:00
NEXT_OPCODE ( ) ;
}
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
2002-10-19 05:19:27 +08:00
int zend_pre_inc_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
zend_pre_incdec_property ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , increment_function 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_pre_dec_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
zend_pre_incdec_property ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , decrement_function 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_post_inc_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
zend_post_incdec_property ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , increment_function 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_post_dec_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
zend_post_incdec_property ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , decrement_function TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-08-18 02:56:54 +08:00
typedef int ( * incdec_t ) ( zval * ) ;
2003-02-10 19:49:21 +08:00
2003-08-18 02:56:54 +08:00
static inline int zend_incdec_op_helper ( incdec_t incdec_op_arg , ZEND_OPCODE_HANDLER_ARGS )
2002-10-19 05:19:27 +08:00
{
2004-02-03 20:17:09 +08:00
zval * * var_ptr = get_zval_ptr_ptr ( & opline - > op1 , EX ( Ts ) , BP_VAR_RW ) ;
2002-10-19 05:19:27 +08:00
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 ) ) {
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . var . ptr_ptr = & EG ( uninitialized_zval_ptr ) ;
SELECTIVE_PZVAL_LOCK ( * EX_T ( opline - > result . u . var ) . var . ptr_ptr , & opline - > result ) ;
AI_USE_PTR ( EX_T ( opline - > result . u . var ) . var ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2004-02-03 20:17:09 +08:00
switch ( opline - > opcode ) {
2002-10-19 05:19:27 +08:00
case ZEND_POST_INC :
case ZEND_POST_DEC :
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . tmp_var = * * var_ptr ;
zendi_zval_copy_ctor ( EX_T ( opline - > result . u . var ) . tmp_var ) ;
2002-10-19 05:19:27 +08:00
break ;
}
SEPARATE_ZVAL_IF_NOT_REF ( var_ptr ) ;
2004-03-25 21:03:04 +08:00
if ( Z_TYPE_PP ( var_ptr ) = = IS_OBJECT & & Z_OBJ_HANDLER_PP ( var_ptr , get )
& & Z_OBJ_HANDLER_PP ( var_ptr , set ) ) {
/* proxy object */
2004-03-26 08:26:19 +08:00
zval * val = Z_OBJ_HANDLER_PP ( var_ptr , get ) ( * var_ptr TSRMLS_CC ) ;
2004-03-25 21:03:04 +08:00
val - > refcount + + ;
incdec_op ( val ) ;
2004-03-26 08:26:19 +08:00
Z_OBJ_HANDLER_PP ( var_ptr , set ) ( var_ptr , val TSRMLS_CC ) ;
2004-03-25 21:03:04 +08:00
zval_ptr_dtor ( & val ) ;
} else {
incdec_op ( * var_ptr ) ;
}
2002-10-19 05:19:27 +08:00
2004-02-03 20:17:09 +08:00
switch ( opline - > opcode ) {
2002-10-19 05:19:27 +08:00
case ZEND_PRE_INC :
case ZEND_PRE_DEC :
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . var . ptr_ptr = var_ptr ;
SELECTIVE_PZVAL_LOCK ( * var_ptr , & opline - > result ) ;
AI_USE_PTR ( EX_T ( 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
2004-03-17 23:48:49 +08:00
int zend_echo_handler ( ZEND_OPCODE_HANDLER_ARGS )
2002-10-19 05:19:27 +08:00
{
2004-03-17 23:48:49 +08:00
zval * free_op1 ;
zval z_copy ;
zval * z = get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & free_op1 , BP_VAR_R ) ;
if ( Z_TYPE_P ( z ) = = IS_OBJECT & & Z_OBJ_HT_P ( z ) - > get_method ! = NULL & &
zend_std_cast_object_tostring ( z , & z_copy , IS_STRING , 0 TSRMLS_CC ) = = SUCCESS ) {
zend_print_variable ( & z_copy ) ;
zval_dtor ( & z_copy ) ;
} else {
zend_print_variable ( z ) ;
}
2004-03-18 00:18:24 +08:00
FREE_OP ( EX ( Ts ) , & opline - > op1 , free_op1 ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2004-03-17 23:48:49 +08:00
int zend_print_handler ( ZEND_OPCODE_HANDLER_ARGS )
2002-10-19 05:19:27 +08:00
{
2004-03-17 23:48:49 +08:00
EX_T ( opline - > result . u . var ) . tmp_var . value . lval = 1 ;
EX_T ( opline - > result . u . var ) . tmp_var . type = IS_LONG ;
return zend_echo_handler ( ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
2002-10-19 05:19:27 +08:00
}
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 )
{
2004-02-03 20:17:09 +08:00
zend_fetch_var_address ( opline , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
AI_USE_PTR ( EX_T ( 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 )
{
2004-02-03 20:17:09 +08:00
zend_fetch_var_address ( opline , EX ( Ts ) , BP_VAR_W 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_fetch_rw_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
zend_fetch_var_address ( opline , EX ( Ts ) , BP_VAR_RW 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_fetch_func_arg_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
if ( ARG_SHOULD_BE_SENT_BY_REF ( EX ( fbc ) , opline - > extended_value ) ) {
2002-10-19 05:19:27 +08:00
/* Behave like FETCH_W */
2004-02-03 20:17:09 +08:00
zend_fetch_var_address ( opline , EX ( Ts ) , BP_VAR_W TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
} else {
/* Behave like FETCH_R */
2004-02-03 20:17:09 +08:00
zend_fetch_var_address ( opline , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
AI_USE_PTR ( EX_T ( 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 )
{
2004-02-03 20:17:09 +08:00
zend_fetch_var_address ( opline , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
PZVAL_UNLOCK ( * EX_T ( opline - > result . u . var ) . var . ptr_ptr ) ;
if ( EX_T ( opline - > result . u . var ) . var . ptr_ptr ! = & EG ( uninitialized_zval_ptr ) ) {
SEPARATE_ZVAL_IF_NOT_REF ( EX_T ( opline - > result . u . var ) . var . ptr_ptr ) ;
2002-10-19 05:19:27 +08:00
}
2004-02-03 20:17:09 +08:00
PZVAL_LOCK ( * EX_T ( 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 )
{
2004-02-03 20:17:09 +08:00
zend_fetch_var_address ( opline , EX ( Ts ) , BP_VAR_IS TSRMLS_CC ) ;
AI_USE_PTR ( EX_T ( 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 )
{
2004-02-03 20:17:09 +08:00
if ( opline - > extended_value = = ZEND_FETCH_ADD_LOCK ) {
PZVAL_LOCK ( * EX_T ( opline - > op1 . u . var ) . var . ptr_ptr ) ;
2002-10-19 05:19:27 +08:00
}
2004-02-03 20:17:09 +08:00
zend_fetch_dimension_address ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
AI_USE_PTR ( EX_T ( 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 )
{
2004-02-03 20:17:09 +08:00
zend_fetch_dimension_address ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , BP_VAR_W 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_fetch_dim_rw_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
zend_fetch_dimension_address ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , BP_VAR_RW 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_fetch_dim_is_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
zend_fetch_dimension_address ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , BP_VAR_IS TSRMLS_CC ) ;
AI_USE_PTR ( EX_T ( 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 )
{
2004-02-03 20:17:09 +08:00
if ( ARG_SHOULD_BE_SENT_BY_REF ( EX ( fbc ) , opline - > extended_value ) ) {
2002-10-19 05:19:27 +08:00
/* Behave like FETCH_DIM_W */
2004-02-03 20:17:09 +08:00
zend_fetch_dimension_address ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , BP_VAR_W TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
} else {
/* Behave like FETCH_DIM_R, except for locking used for list() */
2004-02-03 20:17:09 +08:00
zend_fetch_dimension_address ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
AI_USE_PTR ( EX_T ( 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
2004-02-03 20:17:09 +08:00
if ( opline - > extended_value = = ZEND_FETCH_ADD_LOCK ) {
PZVAL_LOCK ( * EX_T ( opline - > op1 . u . var ) . var . ptr_ptr ) ;
2002-10-19 05:19:27 +08:00
}
*/
2004-02-11 21:58:29 +08:00
zend_fetch_dimension_address ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , BP_VAR_UNSET TSRMLS_CC ) ;
2004-02-03 20:17:09 +08:00
if ( EX_T ( opline - > result . u . var ) . var . ptr_ptr = = NULL ) {
2003-12-19 19:26:52 +08:00
zend_error ( E_ERROR , " Cannot unset string offsets " ) ;
} else {
2004-02-03 20:17:09 +08:00
PZVAL_UNLOCK ( * EX_T ( opline - > result . u . var ) . var . ptr_ptr ) ;
if ( EX_T ( opline - > result . u . var ) . var . ptr_ptr ! = & EG ( uninitialized_zval_ptr ) ) {
SEPARATE_ZVAL_IF_NOT_REF ( EX_T ( opline - > result . u . var ) . var . ptr_ptr ) ;
2003-12-11 18:21:16 +08:00
}
2004-02-03 20:17:09 +08:00
PZVAL_LOCK ( * EX_T ( 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 )
{
2004-02-03 20:17:09 +08:00
zend_fetch_property_address_read ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
AI_USE_PTR ( EX_T ( 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 )
{
2004-02-25 22:56:45 +08:00
if ( opline - > extended_value = = ZEND_FETCH_ADD_LOCK ) {
PZVAL_LOCK ( * EX_T ( opline - > op1 . u . var ) . var . ptr_ptr ) ;
2004-02-26 01:23:50 +08:00
EX_T ( opline - > op1 . u . var ) . var . ptr = * EX_T ( opline - > op1 . u . var ) . var . ptr_ptr ;
2004-02-25 22:56:45 +08:00
}
2004-02-03 20:17:09 +08:00
zend_fetch_property_address ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , BP_VAR_W 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_fetch_obj_rw_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
zend_fetch_property_address ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , BP_VAR_RW 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_fetch_obj_is_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
zend_fetch_property_address_read ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , BP_VAR_IS TSRMLS_CC ) ;
AI_USE_PTR ( EX_T ( 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 )
{
2004-02-03 20:17:09 +08:00
if ( ARG_SHOULD_BE_SENT_BY_REF ( EX ( fbc ) , opline - > extended_value ) ) {
2002-10-19 05:19:27 +08:00
/* Behave like FETCH_OBJ_W */
2004-02-03 20:17:09 +08:00
zend_fetch_property_address ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , BP_VAR_W TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
} else {
2004-02-03 20:17:09 +08:00
zend_fetch_property_address_read ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
AI_USE_PTR ( EX_T ( 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 )
{
2004-02-03 20:17:09 +08:00
zend_fetch_property_address ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
2004-02-03 20:17:09 +08:00
PZVAL_UNLOCK ( * EX_T ( opline - > result . u . var ) . var . ptr_ptr ) ;
if ( EX_T ( opline - > result . u . var ) . var . ptr_ptr ! = & EG ( uninitialized_zval_ptr ) ) {
SEPARATE_ZVAL_IF_NOT_REF ( EX_T ( opline - > result . u . var ) . var . ptr_ptr ) ;
2002-10-19 05:19:27 +08:00
}
2004-02-03 20:17:09 +08:00
PZVAL_LOCK ( * EX_T ( 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 )
{
2004-02-03 20:17:09 +08:00
zend_fetch_dimension_address_from_tmp_var ( & opline - > result , & opline - > op1 , & opline - > op2 , EX ( Ts ) TSRMLS_CC ) ;
AI_USE_PTR ( EX_T ( 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_assign_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
zend_op * op_data = opline + 1 ;
zval * * object_ptr = get_obj_zval_ptr_ptr ( & opline - > op1 , EX ( Ts ) , BP_VAR_W TSRMLS_CC ) ;
2003-07-07 17:00:36 +08:00
2004-02-03 20:17:09 +08:00
zend_assign_to_object ( & opline - > result , object_ptr , & opline - > op2 , & op_data - > op1 , EX ( Ts ) , ZEND_ASSIGN_OBJ TSRMLS_CC ) ;
2003-01-27 23:13:01 +08:00
/* assign_obj has two opcodes! */
2004-02-03 20:17:09 +08:00
INC_OPCODE ( ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2003-07-07 17:00:36 +08:00
int zend_assign_dim_handler ( ZEND_OPCODE_HANDLER_ARGS )
2003-07-07 18:16:05 +08:00
{
2004-02-03 20:17:09 +08:00
zend_op * op_data = opline + 1 ;
2004-02-10 19:39:52 +08:00
zval * * object_ptr ;
if ( EX_T ( opline - > op1 . u . var ) . var . ptr_ptr ) {
/* not an array offset */
object_ptr = get_obj_zval_ptr_ptr ( & opline - > op1 , EX ( Ts ) , BP_VAR_W TSRMLS_CC ) ;
} else {
object_ptr = NULL ;
}
2003-07-07 17:00:36 +08:00
2004-02-10 19:39:52 +08:00
if ( object_ptr & & ( * object_ptr ) - > type = = IS_OBJECT ) {
2004-02-03 20:17:09 +08:00
zend_assign_to_object ( & opline - > result , object_ptr , & opline - > op2 , & op_data - > op1 , EX ( Ts ) , ZEND_ASSIGN_DIM TSRMLS_CC ) ;
2003-07-07 17:00:36 +08:00
} else {
zval * value ;
2004-02-10 19:39:52 +08:00
if ( object_ptr ) {
( * object_ptr ) - > refcount + + ; /* undo the effect of get_obj_zval_ptr_ptr() */
}
2004-03-22 05:29:17 +08:00
zend_fetch_dimension_address ( & op_data - > op2 , & opline - > op1 , & opline - > op2 , EX ( Ts ) , BP_VAR_W TSRMLS_CC ) ;
2003-07-07 17:00:36 +08:00
2004-03-22 05:29:17 +08:00
value = get_zval_ptr ( & op_data - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
zend_assign_to_variable ( & opline - > result , & op_data - > op2 , & op_data - > op1 , value , ( EG ( free_op1 ) ? IS_TMP_VAR : opline - > op1 . op_type ) , EX ( Ts ) TSRMLS_CC ) ;
2003-07-07 17:00:36 +08:00
}
2003-07-25 00:51:35 +08:00
/* assign_dim has two opcodes! */
2004-02-03 20:17:09 +08:00
INC_OPCODE ( ) ;
2003-07-07 17:00:36 +08:00
NEXT_OPCODE ( ) ;
}
2002-10-19 05:19:27 +08:00
int zend_assign_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * value ;
2004-02-03 20:17:09 +08:00
value = get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
2004-02-03 20:17:09 +08:00
zend_assign_to_variable ( & opline - > result , & opline - > op1 , & opline - > op2 , value , ( EG ( free_op2 ) ? IS_TMP_VAR : opline - > op2 . op_type ) , EX ( Ts ) TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
/* 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 )
{
2004-02-03 20:17:09 +08:00
zval * * value_ptr_ptr = get_zval_ptr_ptr ( & opline - > op2 , EX ( Ts ) , BP_VAR_W ) ;
2002-10-19 05:19:27 +08:00
2004-02-03 20:17:09 +08:00
zend_assign_to_variable_reference ( & opline - > result , get_zval_ptr_ptr ( & opline - > op1 , EX ( Ts ) , BP_VAR_W ) , value_ptr_ptr , 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_jmp_handler ( ZEND_OPCODE_HANDLER_ARGS )
2004-03-22 19:16:24 +08:00
{
2002-10-19 05:19:27 +08:00
# if DEBUG_ZEND>=2
2004-02-03 20:17:09 +08:00
printf ( " Jumping to %d \n " , opline - > op1 . u . opline_num ) ;
2002-10-19 05:19:27 +08:00
# endif
2004-02-03 20:17:09 +08:00
SET_OPCODE ( 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 )
{
2004-02-03 20:17:09 +08:00
znode * op1 = & opline - > op1 ;
2002-10-19 05:19:27 +08:00
if ( ! i_zend_is_true ( get_zval_ptr ( op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ) ) {
# if DEBUG_ZEND>=2
2004-02-03 20:17:09 +08:00
printf ( " Conditional jmp to %d \n " , opline - > op2 . u . opline_num ) ;
2002-10-19 05:19:27 +08:00
# endif
2004-02-03 20:17:09 +08:00
SET_OPCODE ( 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 )
{
2004-02-03 20:17:09 +08:00
znode * op1 = & opline - > op1 ;
2002-10-19 05:19:27 +08:00
if ( zend_is_true ( get_zval_ptr ( op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ) ) {
# if DEBUG_ZEND>=2
2004-02-03 20:17:09 +08:00
printf ( " Conditional jmp to %d \n " , opline - > op2 . u . opline_num ) ;
2002-10-19 05:19:27 +08:00
# endif
2004-02-03 20:17:09 +08:00
SET_OPCODE ( 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 )
{
2004-02-03 20:17:09 +08:00
znode * res = & opline - > op1 ;
2002-10-19 05:19:27 +08:00
if ( zend_is_true ( get_zval_ptr ( res , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ) ) {
# if DEBUG_ZEND>=2
2004-02-03 20:17:09 +08:00
printf ( " Conditional jmp on true to %d \n " , opline - > extended_value ) ;
2002-10-19 05:19:27 +08:00
# endif
2004-02-03 20:17:09 +08:00
SET_OPCODE ( & op_array - > opcodes [ opline - > extended_value ] ) ;
2002-10-19 05:19:27 +08:00
} else {
# if DEBUG_ZEND>=2
2004-02-03 20:17:09 +08:00
printf ( " Conditional jmp on false to %d \n " , opline - > op2 . u . opline_num ) ;
2002-10-19 05:19:27 +08:00
# endif
2004-02-03 20:17:09 +08:00
SET_OPCODE ( & op_array - > opcodes [ opline - > op2 . u . opline_num ] ) ;
2002-10-19 05:19:27 +08:00
}
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 )
{
2004-02-03 20:17:09 +08:00
zend_op * original_opline = opline ;
2002-10-19 05:19:27 +08:00
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
2004-02-03 20:17:09 +08:00
printf ( " Conditional jmp to %d \n " , opline - > op2 . u . opline_num ) ;
2002-10-19 05:19:27 +08:00
# endif
2004-02-03 20:17:09 +08:00
SET_OPCODE ( 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 )
{
2004-02-03 20:17:09 +08:00
zend_op * original_opline = opline ;
2002-10-19 05:19:27 +08:00
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
2004-02-03 20:17:09 +08:00
printf ( " Conditional jmp to %d \n " , opline - > op2 . u . opline_num ) ;
2002-10-19 05:19:27 +08:00
# endif
2004-02-03 20:17:09 +08:00
SET_OPCODE ( 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 )
{
2004-02-03 20:17:09 +08:00
zendi_zval_dtor ( EX_T ( 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 )
{
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . tmp_var . value . str . val = emalloc ( 1 ) ;
EX_T ( opline - > result . u . var ) . tmp_var . value . str . val [ 0 ] = 0 ;
EX_T ( opline - > result . u . var ) . tmp_var . value . str . len = 0 ;
EX_T ( opline - > result . u . var ) . tmp_var . refcount = 1 ;
EX_T ( opline - > result . u . var ) . tmp_var . type = IS_STRING ;
EX_T ( 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 )
{
2004-02-03 20:17:09 +08:00
add_char_to_string ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_NA ) ,
& opline - > op2 . u . constant ) ;
2002-10-19 05:19:27 +08:00
/* 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 )
{
2004-02-03 20:17:09 +08:00
add_string_to_string ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_NA ) ,
& opline - > op2 . u . constant ) ;
2002-10-19 05:19:27 +08:00
/* 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 )
{
2004-02-03 20:17:09 +08:00
zval * var = get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
zval var_copy ;
int use_copy ;
zend_make_printable_zval ( var , & var_copy , & use_copy ) ;
if ( use_copy ) {
var = & var_copy ;
}
2004-02-03 20:17:09 +08:00
add_string_to_string ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_NA ) ,
2002-10-19 05:19:27 +08:00
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
*/
2004-02-03 20:17:09 +08:00
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-08-03 16:21:08 +08:00
2002-10-19 05:19:27 +08:00
int zend_fetch_class_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-08-03 16:21:08 +08:00
zval * class_name ;
2002-10-19 05:19:27 +08:00
2003-08-03 16:21:08 +08:00
2004-02-03 20:17:09 +08:00
if ( opline - > op2 . op_type = = IS_UNUSED ) {
EX_T ( opline - > result . u . var ) . class_entry = zend_fetch_class ( NULL , 0 , opline - > extended_value TSRMLS_CC ) ;
2003-08-03 16:21:08 +08:00
NEXT_OPCODE ( ) ;
2002-10-19 05:19:27 +08:00
}
2004-02-03 20:17:09 +08:00
class_name = get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
2003-08-03 16:21:08 +08:00
switch ( class_name - > type ) {
case IS_OBJECT :
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . class_entry = Z_OBJCE_P ( class_name ) ;
2003-08-03 16:21:08 +08:00
break ;
case IS_STRING :
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . class_entry = zend_fetch_class ( Z_STRVAL_P ( class_name ) , Z_STRLEN_P ( class_name ) , ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC ) ;
2003-08-03 16:21:08 +08:00
break ;
default :
zend_error ( E_ERROR , " Class name must be a valid object or a string " ) ;
break ;
2002-10-19 05:19:27 +08:00
}
2004-02-03 20:17:09 +08:00
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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 ) ) ;
2004-02-03 20:17:09 +08:00
if ( opline - > op1 . op_type = = IS_VAR ) {
SELECTIVE_PZVAL_LOCK ( * EX_T ( opline - > op1 . u . var ) . var . ptr_ptr , & opline - > op1 ) ;
2002-12-08 05:37:09 +08:00
}
/* We are not handling overloaded classes right now */
2004-02-03 20:17:09 +08:00
EX ( object ) = get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2002-12-08 05:37:09 +08:00
2004-03-24 18:55:04 +08:00
/* New always returns the object as is_ref=0, therefore, we can just increment the reference count */
EX ( object ) - > refcount + + ; /* For $this pointer */
2002-12-08 05:37:09 +08:00
EX ( fbc ) = EX ( fbc_constructor ) ;
2003-07-03 20:03:11 +08:00
2002-12-08 05:37:09 +08:00
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 ) ) ;
2004-02-03 20:17:09 +08:00
function_name = get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
2003-06-09 15:39:55 +08:00
if ( Z_TYPE_P ( function_name ) ! = IS_STRING ) {
zend_error ( E_ERROR , " Method name must be a string " ) ;
}
2002-10-19 05:19:27 +08:00
function_name_strval = function_name - > value . str . val ;
function_name_strlen = function_name - > value . str . len ;
EX ( calling_scope ) = EG ( scope ) ;
2004-02-03 20:17:09 +08:00
EX ( object ) = get_obj_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
if ( EX ( object ) & & EX ( object ) - > type = = IS_OBJECT ) {
2004-03-16 22:39:07 +08:00
if ( Z_OBJ_HT_P ( EX ( object ) ) - > get_method = = NULL ) {
zend_error ( E_ERROR , " Object does not support method calls " ) ;
}
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 {
2004-03-24 18:55:04 +08:00
if ( ! PZVAL_IS_REF ( EX ( object ) ) ) {
2002-11-06 03:37:31 +08:00
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 ;
2004-03-24 18:55:04 +08:00
}
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 ;
}
2004-02-03 20:17:09 +08:00
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
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_static_method_call_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * function_name ;
zend_class_entry * ce ;
zend_ptr_stack_n_push ( & EG ( arg_types_stack ) , 3 , EX ( fbc ) , EX ( object ) , EX ( calling_scope ) ) ;
2004-02-03 20:17:09 +08:00
ce = EX_T ( opline - > op1 . u . var ) . class_entry ;
if ( opline - > op2 . op_type ! = IS_UNUSED ) {
2003-08-17 20:27:33 +08:00
char * function_name_strval ;
int function_name_strlen ;
2004-02-03 20:17:09 +08:00
zend_bool is_const = ( opline - > op2 . op_type = = IS_CONST ) ;
2002-10-19 05:19:27 +08:00
2003-07-03 20:03:11 +08:00
if ( is_const ) {
2004-02-03 20:17:09 +08:00
function_name_strval = opline - > op2 . u . constant . value . str . val ;
function_name_strlen = opline - > op2 . u . constant . value . str . len ;
2003-07-03 20:03:11 +08:00
} else {
2004-02-03 20:17:09 +08:00
function_name = get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
2003-10-09 21:44:44 +08:00
if ( Z_TYPE_P ( function_name ) ! = IS_STRING ) {
zend_error ( E_ERROR , " Function name must be a string " ) ;
}
2003-07-03 20:03:11 +08:00
function_name_strval = zend_str_tolower_dup ( function_name - > value . str . val , function_name - > value . str . len ) ;
function_name_strlen = function_name - > value . str . len ;
}
2002-10-19 05:19:27 +08:00
2003-07-03 20:03:11 +08:00
EX ( fbc ) = zend_std_get_static_method ( ce , function_name_strval , function_name_strlen TSRMLS_CC ) ;
2003-08-17 20:27:33 +08:00
if ( ! is_const ) {
efree ( function_name_strval ) ;
2004-02-03 20:17:09 +08:00
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2003-08-17 20:27:33 +08:00
}
2003-07-03 20:03:11 +08:00
} else {
if ( ! ce - > constructor ) {
zend_error ( E_ERROR , " Can not call constructor " ) ;
}
EX ( fbc ) = ce - > constructor ;
2002-10-19 05:19:27 +08:00
}
2002-12-07 01:09:44 +08:00
EX ( calling_scope ) = EX ( fbc ) - > common . scope ;
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 ( ) ;
}
int zend_init_fcall_by_name_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * function_name ;
zend_function * function ;
zend_bool is_const ;
2003-09-17 19:06:11 +08:00
char * function_name_strval , * lcname ;
2002-10-19 05:19:27 +08:00
int function_name_strlen ;
zend_ptr_stack_n_push ( & EG ( arg_types_stack ) , 3 , EX ( fbc ) , EX ( object ) , EX ( calling_scope ) ) ;
2004-02-03 20:17:09 +08:00
is_const = ( opline - > op2 . op_type = = IS_CONST ) ;
2002-10-19 05:19:27 +08:00
2003-06-01 02:31:28 +08:00
if ( is_const ) {
2004-02-03 20:17:09 +08:00
function_name_strval = opline - > op2 . u . constant . value . str . val ;
function_name_strlen = opline - > op2 . u . constant . value . str . len ;
2002-10-19 05:19:27 +08:00
} else {
2004-02-03 20:17:09 +08:00
function_name = get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
2003-06-09 15:39:55 +08:00
if ( Z_TYPE_P ( function_name ) ! = IS_STRING ) {
zend_error ( E_ERROR , " Function name must be a string " ) ;
}
2003-09-17 19:06:11 +08:00
function_name_strval = function_name - > value . str . val ;
2003-05-21 02:44:24 +08:00
function_name_strlen = function_name - > value . str . len ;
2002-10-19 05:19:27 +08:00
}
2003-09-17 19:06:11 +08:00
lcname = zend_str_tolower_dup ( function_name_strval , function_name_strlen ) ;
if ( zend_hash_find ( EG ( function_table ) , lcname , function_name_strlen + 1 , ( void * * ) & function ) = = FAILURE ) {
2004-01-07 08:02:04 +08:00
efree ( lcname ) ;
zend_error ( E_ERROR , " Call to undefined function %s() " , function_name_strval ) ;
2003-05-29 04:42:40 +08:00
}
2003-09-17 19:06:11 +08:00
efree ( lcname ) ;
2002-10-19 05:19:27 +08:00
if ( ! is_const ) {
2004-02-03 20:17:09 +08:00
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2003-06-01 02:31:28 +08:00
}
2003-05-29 04:42:40 +08:00
EX ( calling_scope ) = function - > common . scope ;
EX ( object ) = NULL ;
2002-10-19 05:19:27 +08:00
EX ( fbc ) = function ;
NEXT_OPCODE ( ) ;
}
int zend_do_fcall_common_helper ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * * original_return_value ;
zend_class_entry * current_scope ;
zval * current_this ;
2004-02-03 20:17:09 +08:00
int return_value_used = RETURN_VALUE_USED ( opline ) ;
2003-07-03 01:48:18 +08:00
zend_bool should_change_scope ;
2003-08-30 19:40:37 +08:00
if ( EX ( function_state ) . function - > common . fn_flags & ZEND_ACC_ABSTRACT ) {
2003-08-31 19:38:31 +08:00
zend_error ( E_ERROR , " Cannot call abstract method %s::%s() " , EX ( function_state ) . function - > common . scope - > name , EX ( function_state ) . function - > common . function_name ) ;
2003-08-31 07:51:42 +08:00
NEXT_OPCODE ( ) ; /* Never reached */
2003-08-30 19:40:37 +08:00
}
2004-02-03 20:17:09 +08:00
zend_ptr_stack_n_push ( & EG ( argument_stack ) , 2 , ( void * ) opline - > extended_value , NULL ) ;
2002-10-19 05:19:27 +08:00
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . var . ptr_ptr = & EX_T ( opline - > result . u . var ) . var . ptr ;
2002-10-19 05:19:27 +08:00
2003-07-03 01:48:18 +08:00
if ( EX ( function_state ) . function - > type = = ZEND_USER_FUNCTION
| | EX ( function_state ) . function - > common . scope ) {
should_change_scope = 1 ;
current_this = EG ( This ) ;
EG ( This ) = EX ( object ) ;
current_scope = EG ( scope ) ;
EG ( scope ) = EX ( calling_scope ) ;
2003-08-17 20:38:27 +08:00
} else {
should_change_scope = 0 ;
2003-07-03 01:48:18 +08:00
}
2003-02-17 03:10:27 +08:00
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . var . fcall_returned_reference = 0 ;
2003-12-15 00:09:07 +08:00
2004-01-24 04:58:23 +08:00
if ( EX ( function_state ) . function - > common . scope ) {
if ( ! EG ( This ) & & ! ( EX ( function_state ) . function - > common . fn_flags & ZEND_ACC_STATIC ) ) {
int severity ;
2004-03-18 21:28:05 +08:00
char * severity_word ;
2004-01-25 00:59:24 +08:00
if ( EX ( function_state ) . function - > common . fn_flags & ZEND_ACC_ALLOW_STATIC ) {
2004-01-24 04:58:23 +08:00
severity = E_STRICT ;
2004-03-18 21:28:05 +08:00
severity_word = " should not " ;
2004-01-25 00:59:24 +08:00
} else {
severity = E_ERROR ;
2004-03-18 21:28:05 +08:00
severity_word = " cannot " ;
2004-01-24 04:58:23 +08:00
}
2004-03-18 21:28:05 +08:00
zend_error ( severity , " Non-static method %s::%s() %s be called statically " , EX ( function_state ) . function - > common . scope - > name , EX ( function_state ) . function - > common . function_name , severity_word ) ;
2004-01-24 04:58:23 +08:00
}
}
2002-11-06 03:37:31 +08:00
if ( EX ( function_state ) . function - > type = = ZEND_INTERNAL_FUNCTION ) {
2004-02-03 20:17:09 +08:00
ALLOC_ZVAL ( EX_T ( opline - > result . u . var ) . var . ptr ) ;
INIT_ZVAL ( * ( EX_T ( opline - > result . u . var ) . var . ptr ) ) ;
2003-01-12 00:12:44 +08:00
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
if ( EX ( function_state ) . function - > common . arg_info ) {
zend_uint i = 0 ;
zval * * p ;
ulong arg_count ;
p = ( zval * * ) EG ( argument_stack ) . top_element - 2 ;
arg_count = ( ulong ) * p ;
while ( arg_count > 0 ) {
zend_verify_arg_type ( EX ( function_state ) . function , + + i , * ( p - arg_count ) TSRMLS_CC ) ;
arg_count - - ;
}
}
2003-01-12 01:04:16 +08:00
if ( ! zend_execute_internal ) {
/* saves one function call if zend_execute_internal is not used */
2004-02-03 20:17:09 +08:00
( ( zend_internal_function * ) EX ( function_state ) . function ) - > handler ( opline - > extended_value , EX_T ( opline - > result . u . var ) . var . ptr , EX ( object ) , return_value_used TSRMLS_CC ) ;
2003-01-12 00:12:44 +08:00
} 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 ;
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . var . ptr - > is_ref = 0 ;
EX_T ( opline - > result . u . var ) . var . ptr - > refcount = 1 ;
2002-10-19 05:19:27 +08:00
if ( ! return_value_used ) {
2004-02-03 20:17:09 +08:00
zval_ptr_dtor ( & EX_T ( 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 ;
2004-02-03 20:17:09 +08:00
EX_T ( 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 ) ;
2004-02-03 20:17:09 +08:00
EG ( return_value_ptr_ptr ) = EX_T ( 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 ) ;
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . var . fcall_returned_reference = EG ( active_op_array ) - > return_reference ;
2002-10-19 05:19:27 +08:00
2004-02-03 20:17:09 +08:00
if ( return_value_used & & ! EX_T ( opline - > result . u . var ) . var . ptr ) {
2002-10-19 05:19:27 +08:00
if ( ! EG ( exception ) ) {
2004-02-03 20:17:09 +08:00
ALLOC_ZVAL ( EX_T ( opline - > result . u . var ) . var . ptr ) ;
INIT_ZVAL ( * EX_T ( opline - > result . u . var ) . var . ptr ) ;
2002-10-19 05:19:27 +08:00
}
2004-02-03 20:17:09 +08:00
} else if ( ! return_value_used & & EX_T ( opline - > result . u . var ) . var . ptr ) {
zval_ptr_dtor ( & EX_T ( 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 {
2003-07-27 20:46:14 +08:00
/* clean before putting into the cache, since clean
could call dtors , which could use cached hash */
2003-07-27 22:02:46 +08:00
zend_hash_clean ( EX ( function_state ) . function_symbol_table ) ;
2003-07-27 20:46:14 +08:00
* ( + + EG ( symtable_cache_ptr ) ) = EX ( function_state ) . function_symbol_table ;
2002-10-19 05:19:27 +08:00
}
EG ( active_symbol_table ) = calling_symbol_table ;
} else { /* ZEND_OVERLOADED_FUNCTION */
2004-02-03 20:17:09 +08:00
ALLOC_ZVAL ( EX_T ( opline - > result . u . var ) . var . ptr ) ;
INIT_ZVAL ( * ( EX_T ( 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 ) ) {
2004-02-03 20:17:09 +08:00
Z_OBJ_HT_P ( EX ( object ) ) - > call_method ( EX ( fbc ) - > common . function_name , opline - > extended_value , EX_T ( 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 " ) ;
}
2003-08-19 06:31:11 +08:00
if ( EX ( function_state ) . function - > type = = ZEND_OVERLOADED_FUNCTION_TEMPORARY ) {
efree ( EX ( function_state ) . function - > common . function_name ) ;
}
2002-10-19 05:19:27 +08:00
efree ( EX ( fbc ) ) ;
2003-08-19 06:31:11 +08:00
2002-10-19 05:19:27 +08:00
if ( ! return_value_used ) {
2004-02-03 20:17:09 +08:00
zval_ptr_dtor ( & EX_T ( opline - > result . u . var ) . var . ptr ) ;
2003-08-19 06:31:11 +08:00
} else {
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . var . ptr - > is_ref = 0 ;
EX_T ( opline - > result . u . var ) . var . ptr - > refcount = 1 ;
2002-10-19 05:19:27 +08:00
}
}
2003-07-03 01:48:18 +08:00
2003-08-23 23:38:58 +08:00
if ( EG ( This ) ) {
2003-11-05 06:07:59 +08:00
if ( EG ( exception ) & & EX ( fbc ) & & EX ( fbc ) - > common . fn_flags & ZEND_ACC_CTOR ) {
2003-08-24 23:59:19 +08:00
EG ( This ) - > refcount - - ;
2003-08-23 23:38:58 +08:00
zval_ptr_dtor ( & EG ( This ) ) ;
} else if ( should_change_scope ) {
2003-07-03 01:48:18 +08:00
zval_ptr_dtor ( & EG ( This ) ) ;
}
2003-08-23 23:38:58 +08:00
}
if ( should_change_scope ) {
2003-07-03 01:48:18 +08:00
EG ( This ) = current_this ;
EG ( scope ) = current_scope ;
2003-02-17 03:10:27 +08:00
}
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 ) ) ;
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 ) ) {
2004-02-03 20:17:09 +08:00
zend_throw_exception_internal ( NULL TSRMLS_CC ) ;
if ( return_value_used & & EX_T ( opline - > result . u . var ) . var . ptr ) {
zval_ptr_dtor ( & EX_T ( 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_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 )
{
2004-02-03 20:17:09 +08:00
zval * fname = get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
zend_ptr_stack_n_push ( & EG ( arg_types_stack ) , 3 , EX ( fbc ) , EX ( object ) , EX ( calling_scope ) ) ;
2004-02-12 23:23:06 +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 ;
2002-10-19 05:19:27 +08:00
2004-02-03 20:17:09 +08:00
FREE_OP ( EX ( Ts ) , & 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 ;
2003-12-15 00:09:07 +08:00
if ( EG ( active_op_array ) - > return_reference = = ZEND_RETURN_REF ) {
2004-02-03 20:17:09 +08:00
if ( opline - > op1 . op_type = = IS_CONST | | opline - > op1 . op_type = = IS_TMP_VAR ) {
2003-12-15 00:09:07 +08:00
/* Not supposed to happen, but we'll allow it */
zend_error ( E_STRICT , " Only variable references should be returned by reference " ) ;
goto return_by_value ;
}
2004-02-03 20:17:09 +08:00
retval_ptr_ptr = get_zval_ptr_ptr ( & opline - > op1 , EX ( Ts ) , BP_VAR_W ) ;
2002-10-19 05:19:27 +08:00
if ( ! retval_ptr_ptr ) {
2003-12-15 00:09:07 +08:00
zend_error ( E_ERROR , " Cannot return string offsets by reference " ) ;
2002-10-19 05:19:27 +08:00
}
2003-12-18 01:06:34 +08:00
if ( ! ( * retval_ptr_ptr ) - > is_ref ) {
2004-02-03 20:17:09 +08:00
if ( EX_T ( opline - > op1 . u . var ) . var . ptr_ptr = = & EX_T ( opline - > op1 . u . var ) . var . ptr
| | ( opline - > extended_value = = ZEND_RETURNS_FUNCTION & & ! EX_T ( opline - > op1 . u . var ) . var . fcall_returned_reference ) ) {
2003-12-15 00:09:07 +08:00
zend_error ( E_STRICT , " Only variable references should be returned by reference " ) ;
PZVAL_LOCK ( * retval_ptr_ptr ) ; /* undo the effect of get_zval_ptr_ptr() */
goto return_by_value ;
}
2003-07-02 23:06:10 +08:00
}
2002-10-19 05:19:27 +08:00
SEPARATE_ZVAL_TO_MAKE_IS_REF ( retval_ptr_ptr ) ;
( * retval_ptr_ptr ) - > refcount + + ;
( * EG ( return_value_ptr_ptr ) ) = ( * retval_ptr_ptr ) ;
} else {
2003-12-15 00:09:07 +08:00
return_by_value :
2004-02-03 20:17:09 +08:00
retval_ptr = get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
2004-03-24 18:55:04 +08:00
if ( EG ( ze1_compatibility_mode ) & & Z_TYPE_P ( retval_ptr ) = = IS_OBJECT ) {
ALLOC_ZVAL ( * ( EG ( return_value_ptr_ptr ) ) ) ;
* * EG ( return_value_ptr_ptr ) = * retval_ptr ;
INIT_PZVAL ( * EG ( return_value_ptr_ptr ) ) ;
2004-03-28 22:57:29 +08:00
if ( Z_OBJ_HT_P ( retval_ptr ) - > clone_obj = = NULL ) {
2004-03-24 18:55:04 +08:00
zend_error ( E_ERROR , " Trying to clone an uncloneable object of class %s " , Z_OBJCE_P ( retval_ptr ) - > name ) ;
}
2004-03-29 23:20:50 +08:00
zend_error ( E_STRICT , " Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode' " , Z_OBJCE_P ( retval_ptr ) - > name ) ;
2004-03-28 22:57:29 +08:00
( * EG ( return_value_ptr_ptr ) ) - > value . obj = Z_OBJ_HT_P ( retval_ptr ) - > clone_obj ( retval_ptr TSRMLS_CC ) ;
2004-03-24 18:55:04 +08:00
} else if ( ! EG ( free_op1 ) ) { /* Not a temp var */
2002-10-19 05:19:27 +08:00
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 ;
2004-02-03 20:17:09 +08:00
value = get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
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 ) ;
2004-02-03 20:17:09 +08:00
2004-02-12 18:28:33 +08:00
zend_throw_exception_object ( exception 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_catch_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_class_entry * ce ;
2004-02-03 20:17:09 +08:00
/* Check whether an exception has been thrown, if not, jump over code */
2002-10-19 05:19:27 +08:00
if ( EG ( exception ) = = NULL ) {
2004-02-03 20:17:09 +08:00
SET_OPCODE ( & op_array - > opcodes [ opline - > extended_value ] ) ;
2002-10-19 05:19:27 +08:00
return 0 ; /* CHECK_ME */
}
ce = Z_OBJCE_P ( EG ( exception ) ) ;
2004-02-03 20:17:09 +08:00
if ( ce ! = EX_T ( opline - > op1 . u . var ) . class_entry ) {
2002-10-19 05:19:27 +08:00
while ( ce - > parent ) {
2004-02-03 20:17:09 +08:00
if ( ce - > parent = = EX_T ( opline - > op1 . u . var ) . class_entry ) {
2002-10-19 05:19:27 +08:00
goto exception_should_be_taken ;
}
ce = ce - > parent ;
}
2004-02-03 20:17:09 +08:00
if ( opline - > op1 . u . EA . type ) {
zend_throw_exception_internal ( NULL TSRMLS_CC ) ;
NEXT_OPCODE ( ) ;
}
SET_OPCODE ( & op_array - > opcodes [ opline - > extended_value ] ) ;
2002-10-19 05:19:27 +08:00
return 0 ; /* CHECK_ME */
}
exception_should_be_taken :
2004-02-03 20:17:09 +08:00
zend_hash_update ( EG ( active_symbol_table ) , opline - > op2 . u . constant . value . str . val ,
opline - > op2 . u . constant . value . str . len + 1 , & EG ( exception ) , sizeof ( zval * ) , ( void * * ) NULL ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
if ( opline - > extended_value = = ZEND_DO_FCALL_BY_NAME
& & ARG_SHOULD_BE_SENT_BY_REF ( EX ( fbc ) , opline - > op2 . u . opline_num ) ) {
zend_error ( E_ERROR , " Cannot pass parameter %d by reference " , opline - > op2 . u . opline_num ) ;
2002-10-19 05:19:27 +08:00
}
{
zval * valptr ;
zval * value ;
2004-02-03 20:17:09 +08:00
value = get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
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
2003-08-16 05:02:35 +08:00
static inline int zend_send_by_var_helper ( ZEND_OPCODE_HANDLER_ARGS )
2002-10-19 05:19:27 +08:00
{
zval * varptr ;
2004-02-03 20:17:09 +08:00
varptr = get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
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 ) ;
2004-02-03 20:17:09 +08:00
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ; /* for string offsets */
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_send_var_no_ref_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
if ( opline - > extended_value & ZEND_ARG_COMPILE_TIME_BOUND ) { /* Had function_ptr at compile_time */
if ( ! ( opline - > extended_value & ZEND_ARG_SEND_BY_REF ) ) {
2002-10-19 05:19:27 +08:00
return zend_send_by_var_helper ( ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
2004-02-03 20:17:09 +08:00
} else if ( ! ARG_SHOULD_BE_SENT_BY_REF ( EX ( fbc ) , opline - > op2 . u . opline_num ) ) {
2002-10-19 05:19:27 +08:00
return zend_send_by_var_helper ( ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
}
{
zval * varptr ;
2004-02-03 20:17:09 +08:00
varptr = get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
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 ;
2004-02-03 20:17:09 +08:00
varptr_ptr = get_zval_ptr_ptr ( & opline - > op1 , EX ( Ts ) , BP_VAR_W ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
if ( ( opline - > extended_value = = ZEND_DO_FCALL_BY_NAME )
& & ARG_SHOULD_BE_SENT_BY_REF ( EX ( fbc ) , opline - > op2 . u . opline_num ) ) {
2002-10-19 05:19:27 +08:00
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 ;
2004-02-03 20:17:09 +08:00
zend_uint arg_num = opline - > op1 . u . constant . value . lval ;
2002-10-19 05:19:27 +08:00
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
if ( zend_ptr_stack_get_arg ( arg_num , ( void * * ) & param TSRMLS_CC ) = = FAILURE ) {
2004-03-16 18:14:57 +08:00
char * space ;
char * class_name = get_active_class_name ( & space TSRMLS_CC ) ;
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
zend_verify_arg_type ( ( zend_function * ) EG ( active_op_array ) , arg_num , NULL TSRMLS_CC ) ;
2004-03-16 18:14:57 +08:00
zend_error ( E_WARNING , " Missing argument %ld for %s%s%s() " , opline - > op1 . u . constant . value . lval , class_name , space , get_active_function_name ( TSRMLS_C ) ) ;
2004-02-03 20:17:09 +08:00
if ( opline - > result . op_type = = IS_VAR ) {
PZVAL_UNLOCK ( * EX_T ( opline - > result . u . var ) . var . ptr_ptr ) ;
2002-10-19 05:19:27 +08:00
}
} else {
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
zend_verify_arg_type ( ( zend_function * ) EG ( active_op_array ) , arg_num , * param TSRMLS_CC ) ;
if ( PZVAL_IS_REF ( * param ) ) {
2004-03-25 22:03:34 +08:00
zend_assign_to_variable_reference ( NULL , get_zval_ptr_ptr ( & opline - > result , EX ( Ts ) , BP_VAR_W ) , param , NULL TSRMLS_CC ) ;
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
} else {
2004-03-25 22:03:34 +08:00
zend_assign_to_variable ( NULL , & opline - > result , NULL , * param , IS_VAR , EX ( Ts ) TSRMLS_CC ) ;
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +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
int zend_recv_init_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * * param , * assignment_value ;
2004-02-03 20:17:09 +08:00
zend_uint arg_num = opline - > op1 . u . constant . value . lval ;
2002-10-19 05:19:27 +08:00
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
if ( zend_ptr_stack_get_arg ( arg_num , ( void * * ) & param TSRMLS_CC ) = = FAILURE ) {
2004-02-03 20:17:09 +08:00
if ( opline - > op2 . u . constant . type = = IS_CONSTANT | | opline - > op2 . u . constant . type = = IS_CONSTANT_ARRAY ) {
2002-10-19 05:19:27 +08:00
zval * default_value ;
ALLOC_ZVAL ( default_value ) ;
2004-02-03 20:17:09 +08:00
* default_value = opline - > op2 . u . constant ;
if ( opline - > op2 . u . constant . type = = IS_CONSTANT_ARRAY ) {
2002-10-19 05:19:27 +08:00
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 ;
2004-02-03 20:17:09 +08:00
assignment_value = & opline - > op2 . u . constant ;
2002-10-19 05:19:27 +08:00
}
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
zend_verify_arg_type ( ( zend_function * ) EG ( active_op_array ) , arg_num , assignment_value TSRMLS_CC ) ;
2004-03-25 22:03:34 +08:00
zend_assign_to_variable ( NULL , & opline - > result , NULL , assignment_value , IS_VAR , EX ( Ts ) TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
} else {
assignment_value = * param ;
ntroduce infrastructure for supplying information about arguments,
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
2003-08-04 01:40:44 +08:00
zend_verify_arg_type ( ( zend_function * ) EG ( active_op_array ) , arg_num , assignment_value TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
if ( PZVAL_IS_REF ( assignment_value ) ) {
2004-03-25 22:03:34 +08:00
zend_assign_to_variable_reference ( NULL , get_zval_ptr_ptr ( & opline - > result , EX ( Ts ) , BP_VAR_W ) , param , NULL TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
} else {
2004-03-25 22:03:34 +08:00
zend_assign_to_variable ( NULL , & 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 */
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . tmp_var . value . lval = zend_is_true ( get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ) ;
EX_T ( opline - > result . u . var ) . tmp_var . type = IS_BOOL ;
FREE_OP ( EX ( Ts ) , & 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
2003-08-16 05:02:35 +08:00
static inline int zend_brk_cont_helper ( ZEND_OPCODE_HANDLER_ARGS )
2002-10-19 05:19:27 +08:00
{
2004-02-03 20:17:09 +08:00
zval * nest_levels_zval = get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
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 ;
2004-02-03 20:17:09 +08:00
array_offset = opline - > op1 . u . opline_num ;
2002-10-19 05:19:27 +08:00
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
2004-02-03 20:17:09 +08:00
if ( opline - > opcode = = ZEND_BRK ) {
SET_OPCODE ( op_array - > opcodes + jmp_to - > brk ) ;
2002-10-19 05:19:27 +08:00
} else {
2004-02-03 20:17:09 +08:00
SET_OPCODE ( op_array - > opcodes + jmp_to - > cont ) ;
2002-10-19 05:19:27 +08:00
}
2004-02-03 20:17:09 +08:00
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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
2004-02-03 20:17:09 +08:00
if ( opline - > op1 . op_type = = IS_VAR ) {
if ( EX_T ( opline - > op1 . u . var ) . var . ptr_ptr ) {
PZVAL_LOCK ( EX_T ( opline - > op1 . u . var ) . var . ptr ) ;
2002-10-19 05:19:27 +08:00
} else {
switch_expr_is_overloaded = 1 ;
2004-02-03 20:17:09 +08:00
EX_T ( opline - > op1 . u . var ) . str_offset . str - > refcount + + ;
2002-10-19 05:19:27 +08:00
}
}
2004-02-03 20:17:09 +08:00
is_equal_function ( & EX_T ( opline - > result . u . var ) . tmp_var ,
get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ,
get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
2004-02-03 20:17:09 +08:00
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
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 ( ) )
*/
2004-02-03 20:17:09 +08:00
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
EX_T ( opline - > op1 . u . var ) . var . ptr_ptr = NULL ;
AI_USE_PTR ( EX_T ( 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 )
{
2004-02-03 20:17:09 +08:00
zend_switch_free ( opline , 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_new_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-03-10 00:38:37 +08:00
if ( EX_T ( opline - > op1 . u . var ) . class_entry - > ce_flags & ( ZEND_ACC_INTERFACE | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS ) ) {
2003-03-05 19:14:44 +08:00
char * class_type ;
2004-02-03 20:17:09 +08:00
if ( EX_T ( opline - > op1 . u . var ) . class_entry - > ce_flags & ZEND_ACC_INTERFACE ) {
2003-03-05 19:14:44 +08:00
class_type = " interface " ;
} else {
2003-03-07 07:09:57 +08:00
class_type = " abstract class " ;
2003-03-05 19:14:44 +08:00
}
2004-02-03 20:17:09 +08:00
zend_error ( E_ERROR , " Cannot instantiate %s %s " , class_type , EX_T ( opline - > op1 . u . var ) . class_entry - > name ) ;
2002-12-07 01:09:44 +08:00
}
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . var . ptr_ptr = & EX_T ( opline - > result . u . var ) . var . ptr ;
ALLOC_ZVAL ( EX_T ( opline - > result . u . var ) . var . ptr ) ;
object_init_ex ( EX_T ( opline - > result . u . var ) . var . ptr , EX_T ( opline - > op1 . u . var ) . class_entry ) ;
EX_T ( opline - > result . u . var ) . var . ptr - > refcount = 1 ;
2004-03-24 18:55:04 +08:00
EX_T ( opline - > result . u . var ) . var . ptr - > is_ref = 0 ;
2004-01-09 21:52:19 +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
int zend_clone_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
zval * obj = get_obj_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R TSRMLS_CC ) ;
2003-07-02 04:02:27 +08:00
zend_class_entry * ce ;
zend_function * clone ;
2003-07-21 01:46:21 +08:00
zend_object_clone_obj_t clone_call ;
2003-08-04 18:30:42 +08:00
2003-08-04 17:10:52 +08:00
if ( ! obj | | Z_TYPE_P ( obj ) ! = IS_OBJECT ) {
2003-05-20 01:12:56 +08:00
zend_error ( E_WARNING , " __clone method called on non-object " ) ;
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . var . ptr = EG ( error_zval_ptr ) ;
EX_T ( opline - > result . u . var ) . var . ptr - > refcount + + ;
2003-05-20 01:12:56 +08:00
NEXT_OPCODE ( ) ;
}
2003-07-02 04:02:27 +08:00
ce = Z_OBJCE_P ( obj ) ;
2003-07-02 05:30:21 +08:00
clone = ce ? ce - > clone : NULL ;
2003-07-21 01:46:21 +08:00
clone_call = Z_OBJ_HT_P ( obj ) - > clone_obj ;
if ( ! clone_call ) {
zend_error ( E_ERROR , " Trying to clone an uncloneable object of class %s " , ce - > name ) ;
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . var . ptr = EG ( error_zval_ptr ) ;
EX_T ( opline - > result . u . var ) . var . ptr - > refcount + + ;
2003-07-21 01:46:21 +08:00
}
2003-07-02 05:30:21 +08:00
if ( ce & & clone ) {
if ( clone - > op_array . fn_flags & ZEND_ACC_PRIVATE ) {
/* Ensure that if we're calling a private function, we're allowed to do so.
*/
if ( ce ! = EG ( scope ) ) {
2003-09-02 22:08:59 +08:00
zend_error ( E_ERROR , " Call to private %s::__clone() from context '%s' " , ce - > name , EG ( scope ) ? EG ( scope ) - > name : " " ) ;
2003-07-02 05:30:21 +08:00
}
} else if ( ( clone - > common . fn_flags & ZEND_ACC_PROTECTED ) ) {
/* Ensure that if we're calling a protected function, we're allowed to do so.
*/
if ( ! zend_check_protected ( clone - > common . scope , EG ( scope ) ) ) {
2003-09-02 22:08:59 +08:00
zend_error ( E_ERROR , " Call to protected %s::__clone() from context '%s' " , ce - > name , EG ( scope ) ? EG ( scope ) - > name : " " ) ;
2003-07-02 05:30:21 +08:00
}
2003-07-02 04:02:27 +08:00
}
}
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . var . ptr_ptr = & EX_T ( opline - > result . u . var ) . var . ptr ;
ALLOC_ZVAL ( EX_T ( opline - > result . u . var ) . var . ptr ) ;
EX_T ( opline - > result . u . var ) . var . ptr - > value . obj = clone_call ( obj TSRMLS_CC ) ;
2003-07-27 21:20:31 +08:00
if ( EG ( exception ) ) {
2004-02-03 20:17:09 +08:00
FREE_ZVAL ( EX_T ( opline - > result . u . var ) . var . ptr ) ;
} else {
EX_T ( opline - > result . u . var ) . var . ptr - > type = IS_OBJECT ;
EX_T ( opline - > result . u . var ) . var . ptr - > refcount = 1 ;
EX_T ( opline - > result . u . var ) . var . ptr - > is_ref = 1 ;
2003-07-27 21:20:31 +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
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 ;
2004-02-03 20:17:09 +08:00
if ( opline - > op1 . op_type = = IS_UNUSED ) {
2004-03-09 23:27:39 +08:00
/* This seems to be a reminant of namespaces
2002-10-19 05:19:27 +08:00
if ( EG ( scope ) ) {
ce = EG ( scope ) ;
2004-02-03 20:17:09 +08:00
if ( zend_hash_find ( & ce - > constants_table , opline - > op2 . u . constant . value . str . val , opline - > op2 . u . constant . value . str . len + 1 , ( void * * ) & value ) = = SUCCESS ) {
2002-10-19 05:19:27 +08:00
zval_update_constant ( value , ( void * ) 1 TSRMLS_CC ) ;
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . tmp_var = * * value ;
zval_copy_ctor ( & EX_T ( opline - > result . u . var ) . tmp_var ) ;
2000-01-29 08:33:07 +08:00
NEXT_OPCODE ( ) ;
2002-10-19 05:19:27 +08:00
}
}
2004-03-09 23:27:39 +08:00
*/
2004-02-03 20:17:09 +08:00
if ( ! zend_get_constant ( opline - > op2 . u . constant . value . str . val , opline - > op2 . u . constant . value . str . len , & EX_T ( 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' " ,
2004-02-03 20:17:09 +08:00
opline - > op2 . u . constant . value . str . val ,
opline - > op2 . u . constant . value . str . val ) ;
EX_T ( opline - > result . u . var ) . tmp_var = opline - > op2 . u . constant ;
zval_copy_ctor ( & EX_T ( opline - > result . u . var ) . tmp_var ) ;
2002-10-19 05:19:27 +08:00
}
NEXT_OPCODE ( ) ;
}
2004-02-03 20:17:09 +08:00
ce = EX_T ( opline - > op1 . u . var ) . class_entry ;
2002-10-19 05:19:27 +08:00
2004-02-03 20:17:09 +08:00
if ( zend_hash_find ( & ce - > constants_table , opline - > op2 . u . constant . value . str . val , opline - > op2 . u . constant . value . str . len + 1 , ( void * * ) & value ) = = SUCCESS ) {
2002-10-19 05:19:27 +08:00
zval_update_constant ( value , ( void * ) 1 TSRMLS_CC ) ;
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . tmp_var = * * value ;
zval_copy_ctor ( & EX_T ( opline - > result . u . var ) . tmp_var ) ;
2002-10-19 05:19:27 +08:00
} else {
2004-02-03 20:17:09 +08:00
zend_error ( E_ERROR , " Undefined class constant '%s' " , opline - > op2 . u . constant . value . str . val ) ;
2002-10-19 05:19:27 +08:00
}
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
2003-08-16 05:02:35 +08:00
static inline int zend_init_add_array_helper ( ZEND_OPCODE_HANDLER_ARGS )
2002-10-19 05:19:27 +08:00
{
2004-02-03 20:17:09 +08:00
zval * array_ptr = & EX_T ( opline - > result . u . var ) . tmp_var ;
2002-10-19 05:19:27 +08:00
zval * expr_ptr , * * expr_ptr_ptr = NULL ;
2004-02-03 20:17:09 +08:00
zval * offset = get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
2004-02-03 20:17:09 +08:00
if ( opline - > extended_value ) {
expr_ptr_ptr = get_zval_ptr_ptr ( & opline - > op1 , EX ( Ts ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
expr_ptr = * expr_ptr_ptr ;
} else {
2004-02-03 20:17:09 +08:00
expr_ptr = get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
}
2004-02-03 20:17:09 +08:00
if ( opline - > opcode = = ZEND_INIT_ARRAY ) {
2002-10-19 05:19:27 +08:00
array_init ( array_ptr ) ;
if ( ! expr_ptr ) {
NEXT_OPCODE ( ) ;
}
}
2004-02-03 20:17:09 +08:00
if ( ! opline - > extended_value & & EG ( free_op1 ) ) { /* temporary variable */
2002-10-19 05:19:27 +08:00
zval * new_expr ;
ALLOC_ZVAL ( new_expr ) ;
* new_expr = * expr_ptr ;
expr_ptr = new_expr ;
INIT_PZVAL ( expr_ptr ) ;
} else {
2004-02-03 20:17:09 +08:00
if ( opline - > extended_value ) {
2002-10-19 05:19:27 +08:00
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 ;
2003-07-23 00:06:07 +08:00
case IS_STRING :
zend_symtable_update ( array_ptr - > value . ht , offset - > value . str . val , offset - > value . str . len + 1 , & expr_ptr , sizeof ( zval * ) , NULL ) ;
2002-10-19 05:19:27 +08:00
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 ;
}
2004-02-03 20:17:09 +08:00
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
2002-10-19 05:19:27 +08:00
} 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 )
{
2004-02-03 20:17:09 +08:00
zval * expr = get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
zval * result = & EX_T ( 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 ) ;
}
2004-02-03 20:17:09 +08:00
switch ( opline - > extended_value ) {
2002-10-19 05:19:27 +08:00
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 ;
2003-12-30 06:01:47 +08:00
case IS_STRING : {
zval var_copy ;
int use_copy ;
zend_make_printable_zval ( result , & var_copy , & use_copy ) ;
if ( use_copy ) {
zval_dtor ( result ) ;
* result = var_copy ;
}
2002-10-19 05:19:27 +08:00
break ;
2003-12-30 06:01:47 +08:00
}
2002-10-19 05:19:27 +08:00
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 ;
2004-02-03 20:17:09 +08:00
zval * inc_filename = get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
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 ;
}
2004-02-03 20:17:09 +08:00
return_value_used = RETURN_VALUE_USED ( opline ) ;
2002-10-19 05:19:27 +08:00
2004-02-03 20:17:09 +08:00
switch ( opline - > op2 . u . constant . value . lval ) {
2002-10-19 05:19:27 +08:00
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 ) {
2004-02-03 20:17:09 +08:00
new_op_array = zend_compile_file ( & file_handle , ( opline - > op2 . u . constant . value . lval = = ZEND_INCLUDE_ONCE ? ZEND_INCLUDE : ZEND_REQUIRE ) TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
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 {
2004-02-03 20:17:09 +08:00
if ( 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 :
2004-02-03 20:17:09 +08:00
new_op_array = compile_filename ( opline - > op2 . u . constant . value . lval , inc_filename TSRMLS_CC ) ;
2002-10-19 05:19:27 +08:00
break ;
case ZEND_EVAL : {
char * eval_desc = zend_make_compiled_string_description ( " eval()'d code " TSRMLS_CC ) ;
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 ) ;
}
2004-02-03 20:17:09 +08:00
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
EX_T ( opline - > result . u . var ) . var . ptr_ptr = & EX_T ( 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 ;
2004-02-03 20:17:09 +08:00
EG ( return_value_ptr_ptr ) = EX_T ( opline - > result . u . var ) . var . ptr_ptr ;
2002-10-19 05:19:27 +08:00
EG ( active_op_array ) = new_op_array ;
2004-02-03 20:17:09 +08:00
EX_T ( 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 ;
zend_execute ( new_op_array TSRMLS_CC ) ;
EX ( function_state ) . function = saved_function ;
EX ( object ) = saved_object ;
if ( ! return_value_used ) {
2004-02-03 20:17:09 +08:00
if ( EX_T ( opline - > result . u . var ) . var . ptr ) {
zval_ptr_dtor ( & EX_T ( opline - > result . u . var ) . var . ptr ) ;
2002-10-19 05:19:27 +08:00
}
} else { /* return value is used */
2004-02-03 20:17:09 +08:00
if ( ! EX_T ( opline - > result . u . var ) . var . ptr ) { /* there was no return statement */
ALLOC_ZVAL ( EX_T ( opline - > result . u . var ) . var . ptr ) ;
INIT_PZVAL ( EX_T ( opline - > result . u . var ) . var . ptr ) ;
EX_T ( opline - > result . u . var ) . var . ptr - > value . lval = 1 ;
EX_T ( 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 ) {
2004-02-03 20:17:09 +08:00
ALLOC_ZVAL ( EX_T ( opline - > result . u . var ) . var . ptr ) ;
INIT_ZVAL ( * EX_T ( opline - > result . u . var ) . var . ptr ) ;
EX_T ( opline - > result . u . var ) . var . ptr - > value . lval = failure_retval ;
EX_T ( 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 ;
2004-02-03 20:17:09 +08:00
varname = get_zval_ptr ( & 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
}
2004-02-03 20:17:09 +08:00
if ( opline - > op2 . u . EA . type = = ZEND_FETCH_STATIC_MEMBER ) {
zend_std_unset_static_property ( EX_T ( opline - > op2 . u . var ) . class_entry , Z_STRVAL_P ( varname ) , Z_STRLEN_P ( varname ) TSRMLS_CC ) ;
2003-02-17 22:06:39 +08:00
} else {
2004-02-03 20:17:09 +08:00
target_symbol_table = zend_get_target_symbol_table ( opline , EX ( Ts ) , BP_VAR_IS , varname TSRMLS_CC ) ;
2003-02-17 22:06:39 +08:00
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 ) ;
}
2004-02-03 20:17:09 +08:00
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
2002-10-19 05:19:27 +08:00
NEXT_OPCODE ( ) ;
}
2003-02-10 19:49:21 +08:00
2003-07-31 01:12:06 +08:00
2002-10-19 05:19:27 +08:00
int zend_unset_dim_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
zval * * container = get_obj_zval_ptr_ptr ( & opline - > op1 , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
zval * offset = get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
2003-05-23 23:11:15 +08:00
long index ;
2002-10-19 05:19:27 +08:00
if ( container ) {
HashTable * ht ;
2004-02-03 20:17:09 +08:00
if ( opline - > extended_value = = ZEND_UNSET_DIM ) {
2003-08-03 16:23:25 +08:00
switch ( Z_TYPE_PP ( container ) ) {
case IS_ARRAY :
ht = Z_ARRVAL_PP ( container ) ;
break ;
case IS_OBJECT :
ht = NULL ;
if ( ! Z_OBJ_HT_P ( * container ) - > unset_dimension ) {
zend_error ( E_ERROR , " Cannot use object as array " ) ;
}
Z_OBJ_HT_P ( * container ) - > unset_dimension ( * container , offset TSRMLS_CC ) ;
break ;
2003-12-19 19:26:52 +08:00
case IS_STRING :
zend_error ( E_ERROR , " Cannot unset string offsets " ) ;
2003-12-26 03:59:38 +08:00
return 0 ; /* bailed out before */
2003-08-03 16:23:25 +08:00
default :
ht = NULL ;
break ;
}
} else { /* ZEND_UNSET_OBJ */
ht = NULL ;
if ( Z_TYPE_PP ( container ) = = IS_OBJECT ) {
Z_OBJ_HT_P ( * container ) - > unset_property ( * container , offset TSRMLS_CC ) ;
}
2002-10-19 05:19:27 +08:00
}
if ( ht ) {
switch ( offset - > type ) {
case IS_DOUBLE :
case IS_RESOURCE :
case IS_BOOL :
case IS_LONG :
2003-05-23 23:11:15 +08:00
if ( offset - > type = = IS_DOUBLE ) {
index = ( long ) offset - > value . lval ;
} else {
index = offset - > value . lval ;
}
2002-10-19 05:19:27 +08:00
2003-05-23 23:11:15 +08:00
zend_hash_index_del ( ht , index ) ;
break ;
case IS_STRING :
2003-07-23 00:06:07 +08:00
zend_symtable_del ( ht , offset - > value . str . val , offset - > value . str . len + 1 ) ;
2002-10-19 05:19:27 +08:00
break ;
case IS_NULL :
zend_hash_del ( ht , " " , sizeof ( " " ) ) ;
break ;
default :
zend_error ( E_WARNING , " Illegal offset type in unset " ) ;
break ;
}
}
} else {
/* overloaded element */
}
2004-02-03 20:17:09 +08:00
FREE_OP ( EX ( Ts ) , & opline - > op2 , EG ( free_op2 ) ) ;
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_fe_reset_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * array_ptr , * * array_ptr_ptr ;
HashTable * fe_ht ;
2003-10-18 01:19:44 +08:00
zend_object_iterator * iter = NULL ;
zend_class_entry * ce = NULL ;
2002-10-19 05:19:27 +08:00
2004-02-03 20:17:09 +08:00
if ( opline - > extended_value ) {
array_ptr_ptr = get_zval_ptr_ptr ( & opline - > op1 , EX ( Ts ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
if ( array_ptr_ptr = = NULL ) {
MAKE_STD_ZVAL ( array_ptr ) ;
2003-10-18 01:19:44 +08:00
} else if ( Z_TYPE_PP ( array_ptr_ptr ) = = IS_OBJECT ) {
ce = Z_OBJCE_PP ( array_ptr_ptr ) ;
if ( ! ce | | ce - > get_iterator = = NULL ) {
SEPARATE_ZVAL_IF_NOT_REF ( array_ptr_ptr ) ;
( * array_ptr_ptr ) - > refcount + + ;
}
array_ptr = * array_ptr_ptr ;
2002-10-19 05:19:27 +08:00
} else {
SEPARATE_ZVAL_IF_NOT_REF ( array_ptr_ptr ) ;
array_ptr = * array_ptr_ptr ;
array_ptr - > refcount + + ;
}
} else {
2004-02-03 20:17:09 +08:00
array_ptr = get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
if ( EG ( free_op1 ) ) { /* IS_TMP_VAR */
zval * tmp ;
ALLOC_ZVAL ( tmp ) ;
* tmp = * array_ptr ;
INIT_PZVAL ( tmp ) ;
array_ptr = tmp ;
2003-10-18 01:19:44 +08:00
} else if ( Z_TYPE_P ( array_ptr ) = = IS_OBJECT ) {
ce = Z_OBJCE_P ( array_ptr ) ;
2002-10-19 05:19:27 +08:00
} else {
array_ptr - > refcount + + ;
}
}
2003-10-18 01:19:44 +08:00
if ( ce & & ce - > get_iterator ) {
iter = ce - > get_iterator ( ce , array_ptr TSRMLS_CC ) ;
if ( iter ) {
array_ptr = zend_iterator_wrap ( iter TSRMLS_CC ) ;
} else {
array_ptr - > refcount + + ;
}
}
2003-09-08 07:09:30 +08:00
PZVAL_LOCK ( array_ptr ) ;
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . var . ptr = array_ptr ;
EX_T ( opline - > result . u . var ) . var . ptr_ptr = & EX_T ( opline - > result . u . var ) . var . ptr ;
2003-09-08 07:09:30 +08:00
2003-10-18 01:19:44 +08:00
if ( iter ) {
2003-11-07 18:47:47 +08:00
iter - > index = 0 ;
2003-10-18 01:19:44 +08:00
if ( iter - > funcs - > rewind ) {
iter - > funcs - > rewind ( iter TSRMLS_CC ) ;
}
} else if ( ( fe_ht = HASH_OF ( array_ptr ) ) ! = NULL ) {
2002-10-19 05:19:27 +08:00
/* probably redundant */
zend_hash_internal_pointer_reset ( fe_ht ) ;
} else {
2003-08-17 20:17:34 +08:00
zend_error ( E_WARNING , " Invalid argument supplied for foreach() " ) ;
2004-02-03 20:17:09 +08:00
opline + + ;
SET_OPCODE ( op_array - > opcodes + opline - > op2 . u . opline_num ) ;
2003-08-17 20:17:34 +08:00
return 0 ;
2002-10-19 05:19:27 +08:00
}
2003-08-17 20:17:34 +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
int zend_fe_fetch_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
zval * array = get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
zval * result = & EX_T ( opline - > result . u . var ) . tmp_var ;
2002-10-19 05:19:27 +08:00
zval * * value , * key ;
char * str_key ;
2003-07-24 16:36:39 +08:00
uint str_key_len ;
2002-10-19 05:19:27 +08:00
ulong int_key ;
HashTable * fe_ht ;
2003-10-18 01:19:44 +08:00
zend_object_iterator * iter = NULL ;
2003-11-07 18:47:47 +08:00
int key_type ;
2002-10-19 05:19:27 +08:00
PZVAL_LOCK ( array ) ;
2003-10-18 01:19:44 +08:00
switch ( zend_iterator_unwrap ( array , & iter TSRMLS_CC ) ) {
2003-12-26 04:08:22 +08:00
default :
2003-10-18 01:19:44 +08:00
case ZEND_ITER_INVALID :
zend_error ( E_WARNING , " Invalid argument supplied for foreach() " ) ;
2004-02-03 20:17:09 +08:00
SET_OPCODE ( op_array - > opcodes + opline - > op2 . u . opline_num ) ;
2003-10-18 01:19:44 +08:00
return 0 ; /* CHECK_ME */
2004-01-25 21:32:02 +08:00
case ZEND_ITER_PLAIN_OBJECT : {
char * class_name , * prop_name ;
zend_object * zobj = zend_objects_get_address ( array TSRMLS_CC ) ;
2003-10-18 01:19:44 +08:00
fe_ht = HASH_OF ( array ) ;
2004-01-25 21:32:02 +08:00
do {
2003-12-19 04:07:30 +08:00
if ( zend_hash_get_current_data ( fe_ht , ( void * * ) & value ) = = FAILURE ) {
/* reached end of iteration */
2004-02-03 20:17:09 +08:00
SET_OPCODE ( op_array - > opcodes + opline - > op2 . u . opline_num ) ;
2003-12-19 04:07:30 +08:00
return 0 ; /* CHECK_ME */
}
2004-01-25 21:32:02 +08:00
key_type = zend_hash_get_current_key_ex ( fe_ht , & str_key , & str_key_len , & int_key , 0 , NULL ) ;
2003-12-19 04:07:30 +08:00
zend_hash_move_forward ( fe_ht ) ;
2004-01-25 21:32:02 +08:00
} while ( zend_check_property_access ( zobj , str_key TSRMLS_CC ) ! = SUCCESS ) ;
zend_unmangle_property_name ( str_key , & class_name , & prop_name ) ;
str_key_len = strlen ( prop_name ) ;
str_key = estrndup ( prop_name , str_key_len ) ;
str_key_len + + ;
break ;
}
case ZEND_ITER_PLAIN_ARRAY :
fe_ht = HASH_OF ( array ) ;
if ( zend_hash_get_current_data ( fe_ht , ( void * * ) & value ) = = FAILURE ) {
/* reached end of iteration */
2004-02-03 20:17:09 +08:00
SET_OPCODE ( op_array - > opcodes + opline - > op2 . u . opline_num ) ;
2004-01-25 21:32:02 +08:00
return 0 ; /* CHECK_ME */
2003-10-18 01:19:44 +08:00
}
2004-01-25 21:32:02 +08:00
key_type = zend_hash_get_current_key_ex ( fe_ht , & str_key , & str_key_len , & int_key , 1 , NULL ) ;
zend_hash_move_forward ( fe_ht ) ;
2003-10-18 01:19:44 +08:00
break ;
case ZEND_ITER_OBJECT :
2003-11-05 06:07:59 +08:00
/* !iter happens from exception */
2003-11-07 18:47:47 +08:00
if ( iter & & iter - > index + + ) {
/* This could cause an endless loop if index becomes zero again.
* In case that ever happens we need an additional flag . */
iter - > funcs - > move_forward ( iter TSRMLS_CC ) ;
}
2004-03-09 02:05:41 +08:00
if ( ! iter | | iter - > funcs - > valid ( iter TSRMLS_CC ) = = FAILURE ) {
2003-10-18 01:19:44 +08:00
/* reached end of iteration */
2004-02-03 20:17:09 +08:00
SET_OPCODE ( op_array - > opcodes + opline - > op2 . u . opline_num ) ;
2003-10-18 01:19:44 +08:00
return 0 ; /* CHECK_ME */
}
iter - > funcs - > get_current_data ( iter , & value TSRMLS_CC ) ;
2003-11-07 18:47:47 +08:00
if ( iter - > funcs - > get_current_key ) {
key_type = iter - > funcs - > get_current_key ( iter , & str_key , & str_key_len , & int_key TSRMLS_CC ) ;
} else {
key_type = HASH_KEY_IS_LONG ;
int_key = iter - > index ;
}
2003-10-18 01:19:44 +08:00
break ;
2002-10-19 05:19:27 +08:00
}
2003-10-18 01:19:44 +08:00
array_init ( result ) ;
2002-10-19 05:19:27 +08:00
2004-02-03 20:17:09 +08:00
if ( opline - > extended_value ) {
2003-07-24 20:38:33 +08:00
SEPARATE_ZVAL_IF_NOT_REF ( value ) ;
( * value ) - > is_ref = 1 ;
}
2002-10-19 05:19:27 +08:00
( * value ) - > refcount + + ;
zend_hash_index_update ( result - > value . ht , 0 , value , sizeof ( zval * ) , NULL ) ;
ALLOC_ZVAL ( key ) ;
INIT_PZVAL ( key ) ;
2003-11-07 18:47:47 +08:00
switch ( key_type ) {
2002-10-19 05:19:27 +08:00
case HASH_KEY_IS_STRING :
key - > value . str . val = str_key ;
2003-07-24 16:36:39 +08:00
key - > value . str . len = str_key_len - 1 ;
2002-10-19 05:19:27 +08:00
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 ) ;
2003-10-18 01:19:44 +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
int zend_jmp_no_ctor_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zval * object_zval ;
zend_function * constructor ;
2004-02-03 20:17:09 +08:00
if ( opline - > op1 . op_type = = IS_VAR ) {
PZVAL_LOCK ( * EX_T ( opline - > op1 . u . var ) . var . ptr_ptr ) ;
2002-10-19 05:19:27 +08:00
}
2004-02-03 20:17:09 +08:00
object_zval = get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
constructor = Z_OBJ_HT_P ( object_zval ) - > get_constructor ( object_zval TSRMLS_CC ) ;
EX ( fbc_constructor ) = NULL ;
if ( constructor = = NULL ) {
2004-02-03 20:17:09 +08:00
if ( opline - > op1 . u . EA . type & EXT_TYPE_UNUSED ) {
zval_ptr_dtor ( EX_T ( opline - > op1 . u . var ) . var . ptr_ptr ) ;
2004-01-09 21:52:19 +08:00
}
2004-02-03 20:17:09 +08:00
SET_OPCODE ( op_array - > opcodes + opline - > op2 . u . opline_num ) ;
2002-10-19 05:19:27 +08:00
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 )
{
2004-02-03 20:17:09 +08:00
zval tmp , * varname = get_zval_ptr ( & 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
}
2004-02-03 20:17:09 +08:00
if ( opline - > op2 . u . EA . type = = ZEND_FETCH_STATIC_MEMBER ) {
value = zend_std_get_static_property ( EX_T ( opline - > op2 . u . var ) . class_entry , Z_STRVAL_P ( varname ) , Z_STRLEN_P ( varname ) , 1 TSRMLS_CC ) ;
2003-02-17 22:06:39 +08:00
if ( ! value ) {
isset = 0 ;
}
} else {
2004-02-03 20:17:09 +08:00
target_symbol_table = zend_get_target_symbol_table ( opline , EX ( Ts ) , BP_VAR_IS , varname TSRMLS_CC ) ;
2003-02-17 22:06:39 +08:00
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
}
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . tmp_var . type = IS_BOOL ;
2002-10-19 05:19:27 +08:00
2004-02-03 20:17:09 +08:00
switch ( opline - > extended_value ) {
2002-10-19 05:19:27 +08:00
case ZEND_ISSET :
if ( isset & & Z_TYPE_PP ( value ) = = IS_NULL ) {
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . tmp_var . value . lval = 0 ;
2002-10-19 05:19:27 +08:00
} else {
2004-02-03 20:17:09 +08:00
EX_T ( 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 ) ) {
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . tmp_var . value . lval = 1 ;
2002-10-19 05:19:27 +08:00
} else {
2004-02-03 20:17:09 +08:00
EX_T ( 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 ) ;
}
2004-02-03 20:17:09 +08:00
FREE_OP ( EX ( Ts ) , & 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
2003-11-11 00:14:44 +08:00
static int zend_isset_isempty_dim_prop_obj_handler ( int prop_dim , ZEND_OPCODE_HANDLER_ARGS )
2002-10-19 05:19:27 +08:00
{
2004-02-03 20:17:09 +08:00
zval * * container = get_obj_zval_ptr_ptr ( & opline - > op1 , EX ( Ts ) , BP_VAR_R TSRMLS_CC ) ;
zval * offset = get_zval_ptr ( & opline - > op2 , EX ( Ts ) , & EG ( free_op2 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
zval * * value = NULL ;
int result = 0 ;
2003-05-23 23:11:15 +08:00
long index ;
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 :
2003-05-23 23:11:15 +08:00
if ( offset - > type = = IS_DOUBLE ) {
index = ( long ) offset - > value . lval ;
} else {
index = offset - > value . lval ;
}
if ( zend_hash_index_find ( ht , index , ( void * * ) & value ) = = SUCCESS ) {
isset = 1 ;
}
break ;
case IS_STRING :
2003-07-23 00:06:07 +08:00
if ( zend_symtable_find ( ht , offset - > value . str . val , offset - > value . str . len + 1 , ( void * * ) & value ) = = SUCCESS ) {
2002-10-19 05:19:27 +08:00
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 ;
}
2004-02-03 20:17:09 +08:00
switch ( opline - > extended_value ) {
2002-10-19 05:19:27 +08:00
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 ) {
2003-11-11 00:14:44 +08:00
if ( prop_dim ) {
2004-02-03 20:17:09 +08:00
result = Z_OBJ_HT_P ( * container ) - > has_property ( * container , offset , ( opline - > extended_value = = ZEND_ISEMPTY ) TSRMLS_CC ) ;
2003-11-11 00:14:44 +08:00
} else {
2004-02-03 20:17:09 +08:00
result = Z_OBJ_HT_P ( * container ) - > has_dimension ( * container , offset , ( opline - > extended_value = = ZEND_ISEMPTY ) TSRMLS_CC ) ;
2003-11-11 00:14:44 +08:00
}
2003-01-16 08:44:17 +08:00
} else if ( ( * container ) - > type = = IS_STRING ) { /* string offsets */
2004-02-03 20:17:09 +08:00
switch ( opline - > extended_value ) {
2003-01-16 08:44:17 +08:00
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
}
}
}
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . tmp_var . type = IS_BOOL ;
2000-09-13 03:47:25 +08:00
2004-02-03 20:17:09 +08:00
switch ( opline - > extended_value ) {
2002-10-19 05:19:27 +08:00
case ZEND_ISSET :
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . tmp_var . value . lval = result ;
2002-10-19 05:19:27 +08:00
break ;
case ZEND_ISEMPTY :
2004-02-03 20:17:09 +08:00
EX_T ( 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
2004-02-03 20:17:09 +08:00
FREE_OP ( EX ( Ts ) , & 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
2003-11-11 00:14:44 +08:00
int zend_isset_isempty_dim_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-11-11 00:23:12 +08:00
return zend_isset_isempty_dim_prop_obj_handler ( 0 , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
2003-11-11 00:14:44 +08:00
}
int zend_isset_isempty_prop_obj_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2003-11-11 00:23:12 +08:00
return zend_isset_isempty_dim_prop_obj_handler ( 1 , ZEND_OPCODE_HANDLER_ARGS_PASSTHRU ) ;
2003-11-11 00:14:44 +08:00
}
2002-10-19 05:19:27 +08:00
int zend_exit_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
if ( opline - > op1 . op_type ! = IS_UNUSED ) {
2002-10-19 05:19:27 +08:00
zval * ptr ;
2002-10-17 02:29:41 +08:00
2004-02-03 20:17:09 +08:00
ptr = get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
2002-10-19 05:19:27 +08:00
if ( Z_TYPE_P ( ptr ) = = IS_LONG ) {
EG ( exit_status ) = Z_LVAL_P ( ptr ) ;
} else {
zend_print_variable ( ptr ) ;
}
2004-02-03 20:17:09 +08:00
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
2002-10-19 05:19:27 +08:00
}
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 )
{
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . tmp_var . value . lval = EG ( error_reporting ) ;
EX_T ( 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 ;
2004-03-29 08:50:52 +08:00
if ( EG ( error_reporting ) ) {
restored_error_reporting . type = IS_LONG ;
restored_error_reporting . value . lval = EX_T ( opline - > op1 . u . var ) . tmp_var . value . lval ;
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 )
{
2004-02-03 20:17:09 +08:00
zval * value = get_zval_ptr ( & opline - > op1 , EX ( Ts ) , & EG ( free_op1 ) , BP_VAR_R ) ;
1999-04-08 02:10:10 +08:00
2004-02-03 20:17:09 +08:00
EX_T ( opline - > result . u . var ) . tmp_var = * value ;
2002-10-19 05:19:27 +08:00
if ( ! EG ( free_op1 ) ) {
2004-02-03 20:17:09 +08:00
zval_copy_ctor ( & EX_T ( 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 )
{
2004-02-05 00:30:15 +08:00
EX_T ( opline - > result . u . var ) . class_entry = do_bind_class ( opline , EG ( class_table ) , 0 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 )
{
2004-02-05 00:30:15 +08:00
EX_T ( opline - > result . u . var ) . class_entry = do_bind_inherited_class ( opline , EG ( class_table ) , EX_T ( opline - > extended_value ) . class_entry , 0 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 )
{
2004-02-05 00:30:15 +08:00
do_bind_function ( opline , EG ( function_table ) , 0 ) ;
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_ticks_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
if ( + + EG ( ticks_count ) > = opline - > op1 . u . constant . value . lval ) {
2002-10-19 05:19:27 +08:00
EG ( ticks_count ) = 0 ;
if ( zend_ticks_function ) {
2004-02-03 20:17:09 +08:00
zend_ticks_function ( opline - > op1 . u . constant . value . lval ) ;
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
2003-01-15 05:29:23 +08:00
int zend_instanceof_handler ( ZEND_OPCODE_HANDLER_ARGS )
2002-10-19 05:19:27 +08:00
{
2004-02-03 20:17:09 +08:00
zval * expr = get_zval_ptr ( & 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 ) {
2004-02-03 20:17:09 +08:00
result = instanceof_function ( Z_OBJCE_P ( expr ) , EX_T ( opline - > op2 . u . var ) . class_entry TSRMLS_CC ) ;
2003-03-05 19:14:44 +08:00
} else {
result = 0 ;
}
2004-02-03 20:17:09 +08:00
ZVAL_BOOL ( & EX_T ( opline - > result . u . var ) . tmp_var , result ) ;
FREE_OP ( EX ( Ts ) , & opline - > op1 , EG ( free_op1 ) ) ;
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_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-03-05 19:14:44 +08:00
int zend_add_interface_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
2004-02-03 20:17:09 +08:00
zend_class_entry * ce = EX_T ( opline - > op1 . u . var ) . class_entry ;
zend_class_entry * iface = EX_T ( opline - > op2 . u . var ) . class_entry ;
2003-03-05 19:14:44 +08:00
if ( ! ( iface - > ce_flags & ZEND_ACC_INTERFACE ) ) {
zend_error ( E_ERROR , " %s cannot implement %s - it is not an interface " , ce - > name , iface - > name ) ;
}
2004-02-03 20:17:09 +08:00
ce - > interfaces [ opline - > extended_value ] = iface ;
2003-03-05 19:14:44 +08:00
2003-10-23 03:59:58 +08:00
zend_do_implement_interface ( ce , iface TSRMLS_CC ) ;
2003-03-05 19:14:44 +08:00
NEXT_OPCODE ( ) ;
}
2003-03-06 22:31:17 +08:00
2004-02-03 20:17:09 +08:00
int zend_handle_exception_handler ( ZEND_OPCODE_HANDLER_ARGS )
{
zend_uint op_num = EG ( opline_before_exception ) - EG ( active_op_array ) - > opcodes ;
int i ;
int encapsulating_block = - 1 ;
2004-02-11 01:01:55 +08:00
zval * * stack_zval_pp ;
2004-02-03 20:17:09 +08:00
2004-02-11 01:01:55 +08:00
stack_zval_pp = ( zval * * ) EG ( argument_stack ) . top_element - 1 ;
while ( * stack_zval_pp ! = NULL ) {
zval_ptr_dtor ( stack_zval_pp ) ;
EG ( argument_stack ) . top_element - - ;
stack_zval_pp - - ;
}
2004-02-03 20:17:09 +08:00
for ( i = 0 ; i < EG ( active_op_array ) - > last_try_catch ; i + + ) {
2004-02-03 21:42:41 +08:00
if ( EG ( active_op_array ) - > try_catch_array [ i ] . try_op > op_num ) {
/* further blocks will not be relevant... */
2004-02-03 20:17:09 +08:00
break ;
}
2004-02-03 21:42:41 +08:00
if ( op_num > = EG ( active_op_array ) - > try_catch_array [ i ] . try_op
& & op_num < EG ( active_op_array ) - > try_catch_array [ i ] . catch_op ) {
2004-02-03 20:17:09 +08:00
encapsulating_block = i ;
}
}
if ( encapsulating_block = = - 1 ) {
RETURN_FROM_EXECUTE_LOOP ( execute_data ) ;
} else {
SET_OPCODE ( & op_array - > opcodes [ EG ( active_op_array ) - > try_catch_array [ encapsulating_block ] . catch_op ] ) ;
return 0 ;
}
}
2003-07-07 18:47:25 +08:00
int zend_verify_abstract_class_handler ( ZEND_OPCODE_HANDLER_ARGS )
2003-03-07 06:53:23 +08:00
{
2004-02-05 00:30:15 +08:00
zend_verify_abstract_class ( EX_T ( opline - > op1 . u . var ) . class_entry TSRMLS_CC ) ;
2003-03-07 06:53:23 +08:00
NEXT_OPCODE ( ) ;
}
2002-10-19 05:19:27 +08:00
void zend_init_opcodes_handlers ( )
{
2004-03-01 00:00:50 +08:00
memset ( zend_opcode_handlers , sizeof ( zend_opcode_handlers ) , 0 ) ;
2002-10-19 05:19:27 +08:00
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 ;
2003-07-31 01:49:27 +08:00
zend_opcode_handlers [ ZEND_UNSET_DIM_OBJ ] = zend_unset_dim_obj_handler ;
2002-10-19 05:19:27 +08:00
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 ;
2003-11-11 00:14:44 +08:00
zend_opcode_handlers [ ZEND_ISSET_ISEMPTY_PROP_OBJ ] = zend_isset_isempty_prop_obj_handler ;
2002-10-19 05:19:27 +08:00
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-03-05 19:14:44 +08:00
zend_opcode_handlers [ ZEND_ADD_INTERFACE ] = zend_add_interface_handler ;
2003-07-07 18:47:25 +08:00
zend_opcode_handlers [ ZEND_VERIFY_ABSTRACT_CLASS ] = zend_verify_abstract_class_handler ;
2003-07-07 17:00:36 +08:00
zend_opcode_handlers [ ZEND_ASSIGN_DIM ] = zend_assign_dim_handler ;
2004-02-03 20:17:09 +08:00
zend_opcode_handlers [ ZEND_HANDLE_EXCEPTION ] = zend_handle_exception_handler ;
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 :
*/