From 15097151f4a7545c1d359bf86f495eb18b9842db Mon Sep 17 00:00:00 2001 From: Marcus Boerger Date: Wed, 16 Jul 2003 09:48:36 +0000 Subject: [PATCH] Update and remove parts no longer possible --- ext/spl/php_spl.c | 42 +---- ext/spl/php_spl.h | 7 +- ext/spl/spl.php | 70 +------ ext/spl/spl_array.c | 292 +++++++++-------------------- ext/spl/spl_array.h | 7 +- ext/spl/spl_engine.c | 10 +- ext/spl/spl_engine.h | 30 +-- ext/spl/spl_foreach.c | 2 +- ext/spl/tests/array_access_ex.phpt | 154 --------------- 9 files changed, 119 insertions(+), 495 deletions(-) delete mode 100755 ext/spl/tests/array_access_ex.phpt diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index fb8593f2a5..c8a0866726 100755 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -56,7 +56,7 @@ zend_module_entry spl_module_entry = { PHP_RINIT(spl), PHP_RSHUTDOWN(spl), PHP_MINFO(spl), - "0.1", + "0.2", STANDARD_MODULE_PROPERTIES }; /* }}} */ @@ -69,11 +69,6 @@ zend_class_entry *spl_ce_forward_assoc; zend_class_entry *spl_ce_sequence_assoc; zend_class_entry *spl_ce_array_read; zend_class_entry *spl_ce_array_access; -zend_class_entry *spl_ce_array_access_ex; -zend_class_entry *spl_ce_array_writer; -#ifdef SPL_ARRAY_WRITE -zend_class_entry *spl_ce_array_writer_default; -#endif /* SPL_ARRAY_WRITE */ /* {{{ spl_functions_none */ @@ -82,17 +77,6 @@ function_entry spl_functions_none[] = { }; /* }}} */ -static unsigned char first_of_two_force_ref[] = { 2, BYREF_FORCE, BYREF_NONE }; - -/* {{{ spl_array_writer_funcs - */ -function_entry spl_array_writer_funcs[] = { - SPL_CLASS_FE(array_writer_default, __construct, first_of_two_force_ref) - SPL_CLASS_FE(array_writer_default, set, NULL) - {NULL, NULL, NULL} -}; -/* }}} */ - /* {{{ spl_init_globals */ static void spl_init_globals(zend_spl_globals *spl_globals) @@ -110,7 +94,7 @@ static void spl_init_globals(zend_spl_globals *spl_globals) #endif #ifdef SPL_ARRAY_WRITE - ZEND_EXECUTE_HOOK(ZEND_ASSIGN); + ZEND_EXECUTE_HOOK(ZEND_ASSIGN_DIM); #endif /* SPL_ARRAY_WRITE */ } /* }}} */ @@ -152,18 +136,6 @@ PHP_MINIT_FUNCTION(spl) REGISTER_SPL_IMPLEMENT(array_access, array_read); REGISTER_SPL_INTF_FUNC(array_access, set); - REGISTER_SPL_INTERFACE(array_access_ex); - REGISTER_SPL_IMPLEMENT(array_access_ex, array_access); - REGISTER_SPL_INTF_FUNC(array_access_ex, new_writer); - - REGISTER_SPL_INTERFACE(array_writer); - REGISTER_SPL_INTF_FUNC(array_writer, set); - -#ifdef SPL_ARRAY_WRITE - REGISTER_SPL_STD_CLASS(array_writer_default, spl_array_writer_default_create); - REGISTER_SPL_FUNCTIONS(array_writer_default, spl_array_writer_funcs); -#endif - return SUCCESS; } /* }}} */ @@ -203,7 +175,7 @@ PHP_MSHUTDOWN_FUNCTION(spl) #endif #ifdef SPL_ARRAY_WRITE - ZEND_EXECUTE_HOOK_RESTORE(ZEND_ASSIGN); + ZEND_EXECUTE_HOOK_RESTORE(ZEND_ASSIGN_DIM); #endif /* SPL_ARRAY_WRITE */ return SUCCESS; @@ -240,8 +212,6 @@ PHP_MINFO_FUNCTION(spl) php_info_print_table_row(2, "sequence_assoc", foreach); php_info_print_table_row(2, "array_read", array_read); php_info_print_table_row(2, "array_access", array_write); - php_info_print_table_row(2, "array_access_ex", array_write); - php_info_print_table_row(2, "array_writer", array_write); php_info_print_table_end(); } /* }}} */ @@ -295,12 +265,6 @@ PHP_FUNCTION(spl_classes) SPL_ADD_CLASS(sequence_assoc); SPL_ADD_CLASS(array_read); SPL_ADD_CLASS(array_access); - SPL_ADD_CLASS(array_access_ex); - SPL_ADD_CLASS(array_writer); - -#ifdef SPL_ARRAY_WRITE - SPL_ADD_CLASS(array_writer_default); -#endif } /* }}} */ diff --git a/ext/spl/php_spl.h b/ext/spl/php_spl.h index 3ae3b636da..e4abfd4514 100755 --- a/ext/spl/php_spl.h +++ b/ext/spl/php_spl.h @@ -70,7 +70,7 @@ ZEND_BEGIN_MODULE_GLOBALS(spl) ZEND_EXECUTE_HOOK_PTR(ZEND_FETCH_DIM_RW); #endif #ifdef SPL_ARRAY_WRITE - ZEND_EXECUTE_HOOK_PTR(ZEND_ASSIGN); + ZEND_EXECUTE_HOOK_PTR(ZEND_ASSIGN_DIM); #endif ZEND_END_MODULE_GLOBALS(spl) @@ -90,11 +90,6 @@ extern zend_class_entry *spl_ce_forward_assoc; extern zend_class_entry *spl_ce_sequence_assoc; extern zend_class_entry *spl_ce_array_read; extern zend_class_entry *spl_ce_array_access; -extern zend_class_entry *spl_ce_array_access_ex; -extern zend_class_entry *spl_ce_array_writer; -#ifdef SPL_ARRAY_WRITE -extern zend_class_entry *spl_ce_array_writer_default; -#endif /* SPL_ARRAY_WRITE */ PHP_FUNCTION(spl_classes); PHP_FUNCTION(class_parents); diff --git a/ext/spl/spl.php b/ext/spl/spl.php index 5e21888dd3..e52a15a214 100755 --- a/ext/spl/spl.php +++ b/ext/spl/spl.php @@ -226,79 +226,11 @@ interface spl_array_read { } \endcode */ -interface spl_array_access extends spl_array_read { +interface spl_array_access implements spl_array_read { /*! Set the value identified by $index to $value. */ function set($value, $index); } -/*! \brief array read/write access with customized array_writer - * - * The internal structure requires that write access via interfaces - * is divided into two parts. First the index is used to create an - * array_writer which will later receive the new value and calls the - * containers set() method with appropriate parameters. - * - * Sometimes it is helpfull to overwrite this behavior and have your - * own implementation for the array_writer. - * - * The following example shows how to use a customized array_writer: - * \code - class array_emulation_ex extends array_emulation implemets spl_array_access_ex { - private $last_index = NULL; - function new_writer($index) { - $last_index = $index; - return new array_write(&$this, $index); - } - } - \endcode - */ -interface spl_array_access_ex extends spl_array_access { - - /*! Create an array_writer interface for the specified index. - * - * If your container uses array_access instead of array_access_ex - * the following code would be equal to the internal new_writer() - * method: - \code - function new_writer($index) { - return new array_write(&$this, $index); - } - \endcode - */ - function new_writer($index); -} - -/*! \brief array writer interface - * - * for every write access to an array_access instance an array_writer - * is created which receives the originating object and the index as - * parameters for the constructor call. - * - * The following shows the equivalent php code for the default - * implementation array_write. - * \code - class array_write implements array_writer { - private $obj; - private $idx; - function __construct(&$obj, $index = null) { - $this->obj = $obj; - $this->idx = $index; - } - function set($value) { - return $this->obj->set($this->idx, $value); - } - } - \endcode - * - * See array_access for more. - */ -interface spl_array_writer { - - /*! Set the corresponding value to $value. - */ - function set($value); -} - ?> \ No newline at end of file diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 5a6c034f6a..87a081a9e6 100755 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -46,139 +46,32 @@ #define AI_PTR_2_PTR_PTR(ai) \ (ai).ptr_ptr = &((ai).ptr) -/* {{{ spl_array_writer_default stuff */ -typedef struct { - zval *obj; - zval *idx; - int locked; -} spl_array_writer_object; - -static zend_class_entry *spl_array_writer_default_get_class(zval *object TSRMLS_DC) -{ -#ifdef SPL_ARRAY_WRITE - return spl_ce_array_writer_default; -#else - return (zend_class_entry *)1; /* force an error here: this ensures not equal */ -#endif -} - -static zend_object_handlers spl_array_writer_default_handlers = { - ZEND_OBJECTS_STORE_HANDLERS, - - NULL, /* read_property */ - NULL, /* write_property */ - NULL, /* get_property_ptr */ - NULL, /* get_property_zval_ptr */ - NULL, /* get */ - NULL, /* set */ - NULL, /* has_property */ - NULL, /* unset_property */ - NULL, /* get_properties */ - NULL, /* get_method */ - NULL, /* call_method */ - NULL, /* get_constructor */ - spl_array_writer_default_get_class, /* get_class_entry */ - NULL, /* get_class_name */ - NULL /* compare_objects */ -}; -/* }}} */ - -/* {{{ spl_array_writer_dtor */ -void spl_array_writer_default_dtor(void *object, zend_object_handle handle TSRMLS_DC) -{ - spl_array_writer_object *writer = (spl_array_writer_object*) object; - - if (writer->obj) - { - writer->obj->refcount--; -/* DELETE_ZVAL(writer->obj); */ - } - if (writer->idx) - { - if (writer->locked) { - PZVAL_UNLOCK(writer->idx); - } else { - writer->idx->refcount--; - DELETE_ZVAL(writer->idx); - } - } - efree(writer); -} -/* }}} */ - -/* {{{ spl_array_writer_default_create */ -zend_object_value spl_array_writer_default_create(zend_class_entry *class_type TSRMLS_DC) -{ - zend_object_value retval; - spl_array_writer_object *intern; - - intern = ecalloc(sizeof(spl_array_writer_object), 1); - - retval.handle = zend_objects_store_put(intern, spl_array_writer_default_dtor, NULL TSRMLS_CC); - retval.handlers = &spl_array_writer_default_handlers; - - return retval; -} -/* }}} */ - -/* {{{ spl_array_writer_default_set */ -void spl_array_writer_default_set(zval *object, zval *newval, zval **retval TSRMLS_DC) +/* {{{ spl_fetch_dimension_address */ +int spl_fetch_dimension_address(znode *result, znode *op1, znode *op2, temp_variable *Ts, int type TSRMLS_DC) { - spl_array_writer_object *writer; + zval **obj; + zend_class_entry *obj_ce; + spl_is_a is_a; - writer = (spl_array_writer_object *) zend_object_store_get_object(object TSRMLS_CC); - spl_begin_method_call_arg_ex2(&writer->obj, NULL, NULL, "set", sizeof("set")-1, retval, writer->idx, newval TSRMLS_CC); -} -/* }}} */ + obj = spl_get_zval_ptr_ptr(op1, Ts TSRMLS_CC); -/* {{{ SPL_CLASS_FUNCTION(array_writer_default, __construct) */ -SPL_CLASS_FUNCTION(array_writer_default, __construct) -{ - zval *object = getThis(); - zval *obj, *idx; - spl_array_writer_object *writer; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &obj, &idx) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Failed to parse parameters"); - return; + if (!obj || (obj_ce = spl_get_class_entry(*obj TSRMLS_CC)) == NULL) { + return 1; } - writer = (spl_array_writer_object *) zend_object_store_get_object(object TSRMLS_CC); - writer->obj = obj; obj->refcount++; - writer->idx = idx; idx->refcount++; -} -/* }}} */ -/* {{{ SPL_CLASS_FUNCTION(array_writer_default, set) */ -SPL_CLASS_FUNCTION(array_writer_default, set) -{ - zval *object = getThis(); - zval *newval; + is_a = spl_implements(obj_ce); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &newval) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Failed to parse parameters"); - return; - } - spl_array_writer_default_set(object, newval, &return_value TSRMLS_CC); -} -/* }}} */ - -/* {{{ spl_fetch_dimension_address */ -int spl_fetch_dimension_address(znode *result, znode *op1, znode *op2, temp_variable *Ts, int type TSRMLS_DC) -{ - zval **container_ptr = spl_get_zval_ptr_ptr(op1, Ts TSRMLS_CC); - - if (spl_is_instance_of(container_ptr, spl_ce_array_read TSRMLS_CC)) { + if (is_a & SPL_IS_A_ARRAY_READ) { zval **retval = &(T(result->u.var).var.ptr); zval *dim = spl_get_zval_ptr(op2, Ts, &EG(free_op2) TSRMLS_CC); zval *exists; - /*ALLOC_ZVAL(exists); not needed */ - spl_begin_method_call_arg_ex1(container_ptr, NULL, NULL, "exists", sizeof("exists")-1, &exists, dim TSRMLS_CC); + spl_begin_method_call_arg_ex1(obj, obj_ce, NULL, "exists", sizeof("exists")-1, &exists, dim TSRMLS_CC); if (!i_zend_is_true(exists)) { if (type == BP_VAR_R || type == BP_VAR_RW) { SEPARATE_ZVAL(&dim); convert_to_string_ex(&dim); - zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(dim)); + zend_error(E_NOTICE, "Undefined index: %s", Z_STRVAL_P(dim)); DELETE_ZVAL(dim); } if (type == BP_VAR_R || type == BP_VAR_IS) { @@ -192,37 +85,8 @@ int spl_fetch_dimension_address(znode *result, znode *op1, znode *op2, temp_vari } DELETE_RET_ZVAL(exists); if (type == BP_VAR_R || type == BP_VAR_IS) { - spl_begin_method_call_arg_ex1(container_ptr, NULL, NULL, "get", sizeof("get")-1, retval, dim TSRMLS_CC); - (*retval)->refcount--; - } else -#ifdef SPL_ARRAY_WRITE - if (spl_is_instance_of(container_ptr, spl_ce_array_access_ex TSRMLS_CC)) { - /* array_access_ex instaces have their own way of creating an access_writer */ - spl_begin_method_call_arg_ex1(container_ptr, NULL, NULL, "new_writer", sizeof("new_writer")-1, retval, dim TSRMLS_CC); - T(result->u.var).var.ptr = *retval; - AI_PTR_2_PTR_PTR(T(result->u.var).var); - SELECTIVE_PZVAL_LOCK(*retval, result); - } else if (spl_is_instance_of(container_ptr, spl_ce_array_access TSRMLS_CC)) { - /* array_access instances create the default array_writer: array_write */ - spl_array_writer_object *writer; - spl_instanciate(spl_ce_array_writer_default, retval TSRMLS_CC); - T(result->u.var).var.ptr = *retval; - AI_PTR_2_PTR_PTR(T(result->u.var).var); - writer = (spl_array_writer_object *) zend_object_store_get_object(*retval TSRMLS_CC); - writer->obj = *container_ptr; - writer->obj->refcount++; - writer->idx = dim; - PZVAL_LOCK(writer->idx); - writer->locked = 1; - SELECTIVE_PZVAL_LOCK(*retval, result); - } else { - zend_error(E_ERROR, "Object must implement spl_array_access for write access"); - retval = &EG(error_zval_ptr); + spl_begin_method_call_arg_ex1(obj, obj_ce, NULL, "get", sizeof("get")-1, retval, dim TSRMLS_CC); } - SELECTIVE_PZVAL_LOCK(*retval, result); -#else - zend_error(E_ERROR, "SPL compiled without array write hook"); -#endif FREE_OP(Ts, op2, EG(free_op2)); return 0; } @@ -279,66 +143,90 @@ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FETCH_DIM_RW) #endif /* }}} */ -/* {{{ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_ASSIGN) */ -#ifdef SPL_ARRAY_WRITE -ZEND_EXECUTE_HOOK_FUNCTION(ZEND_ASSIGN) +static inline zval **spl_get_obj_zval_ptr_ptr(znode *op, temp_variable *Ts, int type TSRMLS_DC) { - zval **writer = spl_get_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC); - zval *newval, *retval, *target; - znode *result; - - if (writer && *writer && Z_TYPE_PP(writer) == IS_OBJECT) { - /* optimization: do pre checks and only test for handlers in case of - * spl_array_writer_default, for spl_array_writer we must use the - * long way of calling spl_instance - * if (spl_is_instance_of(writer, spl_ce_array_writer_default TSRMLS_CC)) - */ - if ((*writer)->value.obj.handlers == &spl_array_writer_default_handlers) { - newval = spl_get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2) TSRMLS_CC); - spl_array_writer_default_set(*writer, newval, &retval TSRMLS_CC); - } else if (spl_is_instance_of(writer, spl_ce_array_writer TSRMLS_CC)) { - newval = spl_get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2) TSRMLS_CC); - spl_begin_method_call_arg_ex1(writer, NULL, NULL, "set", sizeof("set")-1, &retval, newval TSRMLS_CC); + if (op->op_type == IS_UNUSED) { + if (EG(This)) { + /* this should actually never be modified, _ptr_ptr is modified only when + the object is empty */ + return &EG(This); } else { - ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_ASSIGN); + zend_error(E_ERROR, "Using $this when not in object context"); } - } else { - ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_ASSIGN); } - spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC); - - result = &EX(opline)->result; - if (result) { - if (retval->refcount<2) { - if ((*writer)->value.obj.handlers == &spl_array_writer_default_handlers) { - spl_array_writer_object *object = (spl_array_writer_object *) zend_object_store_get_object(*writer TSRMLS_CC); - target = object->obj; - } else { - target = *writer; - } - zend_error(E_WARNING, "Method %s::set() did not return a value, using NULL", Z_OBJCE_P(target)->name); - DELETE_ZVAL(retval); - DELETE_ZVAL(newval); - /* Unfortunately it doesn't work when trying to return newval. - * But anyhow it wouldn't make sense...and confuse reference counting and such. - */ - retval = &EG(uninitialized_zval); - } else { - retval->refcount--; - } - EX_T(EX(opline)->result.u.var).var.ptr = retval; - AI_PTR_2_PTR_PTR(EX_T(EX(opline)->result.u.var).var); - SELECTIVE_PZVAL_LOCK(retval, result); - } else { - retval->refcount = 1; - DELETE_ZVAL(retval); + return spl_get_zval_ptr_ptr(op, Ts TSRMLS_CC); +} + +/* {{{ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_ASSIGN_DIM) */ +#ifdef SPL_ARRAY_WRITE +ZEND_EXECUTE_HOOK_FUNCTION(ZEND_ASSIGN_DIM) +{ + zval **obj; + zend_class_entry *obj_ce; + spl_is_a is_a; + + obj = spl_get_obj_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), 0 TSRMLS_CC); + + if (!obj || (obj_ce = spl_get_class_entry(*obj TSRMLS_CC)) == NULL) { + ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_ASSIGN_DIM); } - (*writer)->refcount = 1; - DELETE_ZVAL(*writer); - FREE_OP(EX(Ts), &EX(opline)->op2, EG(free_op2)); + is_a = spl_implements(obj_ce); + + if (is_a & SPL_IS_A_ARRAY_ACCESS) { + znode *op2 = &EX(opline)->op2; + zval *index = spl_get_zval_ptr(op2, EX(Ts), &EG(free_op2), BP_VAR_R); + zval *free_value; + zend_op *value_op = EX(opline)+1; + zval *value = spl_get_zval_ptr(&value_op->op1, EX(Ts), &free_value, BP_VAR_R); + zval tmp; + zval *retval; + + spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC); + + /* here we are sure we are dealing with an object */ + switch (op2->op_type) { + case IS_CONST: + /* already a constant string */ + break; + case IS_VAR: + tmp = *index; + zval_copy_ctor(&tmp); + convert_to_string(&tmp); + index = &tmp; + break; + case IS_TMP_VAR: + convert_to_string(index); + break; + } + + /* separate our value if necessary */ + if (value_op->op1.op_type == IS_TMP_VAR) { + zval *orig_value = value; + + ALLOC_ZVAL(value); + *value = *orig_value; + value->is_ref = 0; + value->refcount = 0; + } + + spl_begin_method_call_arg_ex2(obj, obj_ce, NULL, "set", sizeof("set")-1, &retval, index, value TSRMLS_CC); - NEXT_OPCODE(); + if (index == &tmp) { + zval_dtor(index); + } + + FREE_OP(Ts, op2, EG(free_op2)); + if (&EX(opline)->result) { + EX_T(EX(opline)->result.u.var).var.ptr = retval; + EX_T(EX(opline)->result.u.var).var.ptr_ptr = NULL;/*&EX_T(EX(opline)->result.u.var).var.ptr;*/ + SELECTIVE_PZVAL_LOCK(retval, &EX(opline)->result); + } + + EX(opline)++; + NEXT_OPCODE(); + } + ZEND_EXECUTE_HOOK_ORIGINAL(ZEND_ASSIGN_DIM); } #endif /* }}} */ diff --git a/ext/spl/spl_array.h b/ext/spl/spl_array.h index 2b75753a31..3aa194c8cc 100755 --- a/ext/spl/spl_array.h +++ b/ext/spl/spl_array.h @@ -29,14 +29,9 @@ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FETCH_DIM_RW); #endif #ifdef SPL_ARRAY_WRITE -ZEND_EXECUTE_HOOK_FUNCTION(ZEND_ASSIGN); +ZEND_EXECUTE_HOOK_FUNCTION(ZEND_ASSIGN_DIM); #endif -SPL_CLASS_FUNCTION(array_writer_default, __construct); -SPL_CLASS_FUNCTION(array_writer_default, set); - -zend_object_value spl_array_writer_default_create(zend_class_entry *class_type TSRMLS_DC); - #endif /* SPL_ARRAY_H */ /* diff --git a/ext/spl/spl_engine.c b/ext/spl/spl_engine.c index 692be6d094..35d233c7d1 100755 --- a/ext/spl/spl_engine.c +++ b/ext/spl/spl_engine.c @@ -158,10 +158,12 @@ spl_is_a spl_implements(zend_class_entry *ce) register zend_class_entry **pce = ce->interfaces; while (i--) { - if (*pce == spl_ce_iterator) is_a |= SPL_IS_A_ITERATOR; - else if (*pce == spl_ce_forward) is_a |= SPL_IS_A_FORWARD; - else if (*pce == spl_ce_assoc) is_a |= SPL_IS_A_ASSOC; - else if (*pce == spl_ce_sequence) is_a |= SPL_IS_A_SEQUENCE; + if (*pce == spl_ce_iterator) is_a |= SPL_IS_A_ITERATOR; + else if (*pce == spl_ce_forward) is_a |= SPL_IS_A_FORWARD; + else if (*pce == spl_ce_assoc) is_a |= SPL_IS_A_ASSOC; + else if (*pce == spl_ce_sequence) is_a |= SPL_IS_A_SEQUENCE; + else if (*pce == spl_ce_array_read) is_a |= SPL_IS_A_ARRAY_READ; + else if (*pce == spl_ce_array_access) is_a |= SPL_IS_A_ARRAY_ACCESS; pce++; } return is_a; diff --git a/ext/spl/spl_engine.h b/ext/spl/spl_engine.h index e20ea39bb6..f3a16472e5 100755 --- a/ext/spl/spl_engine.h +++ b/ext/spl/spl_engine.h @@ -50,10 +50,10 @@ static inline zend_class_entry *spl_get_class_entry(zval *obj TSRMLS_DC) /* }}} */ /* {{{ spl_begin_method_call_arg */ -static inline int spl_begin_method_call_arg(zval **ce, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int fname_len, zval *retval, zval *arg1 TSRMLS_DC) +static inline int spl_begin_method_call_arg(zval **obj, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int fname_len, zval *retval, zval *arg1 TSRMLS_DC) { zval *local_retval; - int ret = spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, &local_retval, NULL TSRMLS_CC, 1, arg1); + int ret = spl_call_method(obj, obj_ce, fn_proxy, function_name, fname_len, &local_retval, NULL TSRMLS_CC, 1, arg1); if (local_retval) { COPY_PZVAL_TO_ZVAL(*retval, local_retval); } else { @@ -64,10 +64,10 @@ static inline int spl_begin_method_call_arg(zval **ce, zend_class_entry *obj_ce, /* }}} */ /* {{{ spl_begin_method_call_no_retval */ -static inline int spl_begin_method_call_no_retval(zval **ce, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int fname_len TSRMLS_DC) +static inline int spl_begin_method_call_no_retval(zval **obj, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int fname_len TSRMLS_DC) { zval *retval; - int ret = spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, &retval, NULL TSRMLS_CC, 0); + int ret = spl_call_method(obj, obj_ce, fn_proxy, function_name, fname_len, &retval, NULL TSRMLS_CC, 0); if (retval) { zval_dtor(retval); FREE_ZVAL(retval); @@ -76,14 +76,14 @@ static inline int spl_begin_method_call_no_retval(zval **ce, zend_class_entry *o } /* }}} */ -#define spl_begin_method_call_ex(ce, obj_ce, fn_proxy, function_name, fname_len, retval) \ - spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 0) +#define spl_begin_method_call_ex(obj, obj_ce, fn_proxy, function_name, fname_len, retval) \ + spl_call_method(obj, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 0) -#define spl_begin_method_call_arg_ex1(ce, obj_ce, fn_proxy, function_name, fname_len, retval, arg1) \ - spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 1, arg1) +#define spl_begin_method_call_arg_ex1(obj, obj_ce, fn_proxy, function_name, fname_len, retval, arg1) \ + spl_call_method(obj, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 1, arg1) -#define spl_begin_method_call_arg_ex2(ce, obj_ce, fn_proxy, function_name, fname_len, retval, arg1, arg2) \ - spl_call_method(ce, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 2, arg1, arg2) +#define spl_begin_method_call_arg_ex2(obj, obj_ce, fn_proxy, function_name, fname_len, retval, arg1, arg2) \ + spl_call_method(obj, obj_ce, fn_proxy, function_name, fname_len, retval, NULL TSRMLS_CC, 2, arg1, arg2) void spl_instanciate(zend_class_entry *pce, zval **object TSRMLS_DC); int spl_instanciate_arg_ex2(zend_class_entry *pce, zval **retval, zval *arg1, zval *arg2, HashTable *symbol_table TSRMLS_DC); @@ -95,10 +95,12 @@ zval * spl_get_zval_ptr(znode *node, temp_variable *Ts, zval **should_free TSRML int spl_is_instance_of(zval **obj, zend_class_entry *ce TSRMLS_DC); typedef enum { - SPL_IS_A_ITERATOR = 1, - SPL_IS_A_FORWARD = 2, - SPL_IS_A_ASSOC = 4, - SPL_IS_A_SEQUENCE = 8 + SPL_IS_A_ITERATOR = 0x01, + SPL_IS_A_FORWARD = 0x02, + SPL_IS_A_ASSOC = 0x04, + SPL_IS_A_SEQUENCE = 0x08, + SPL_IS_A_ARRAY_READ = 0x10, + SPL_IS_A_ARRAY_ACCESS = 0x20 } spl_is_a; spl_is_a spl_implements(zend_class_entry *ce); diff --git a/ext/spl/spl_foreach.c b/ext/spl/spl_foreach.c index 9466a0ad1e..35414f478b 100755 --- a/ext/spl/spl_foreach.c +++ b/ext/spl/spl_foreach.c @@ -69,8 +69,8 @@ ZEND_EXECUTE_HOOK_FUNCTION(ZEND_FE_RESET) if (is_a & SPL_IS_A_ITERATOR) { spl_unlock_zval_ptr_ptr(&EX(opline)->op1, EX(Ts) TSRMLS_CC); - spl_begin_method_call_ex(obj, NULL, NULL, "new_iterator", sizeof("new_iterator")-1, &retval); obj_ce = instance_ce; + spl_begin_method_call_ex(obj, obj_ce, NULL, "new_iterator", sizeof("new_iterator")-1, &retval); instance_ce = spl_get_class_entry(retval TSRMLS_CC); is_a = spl_implements(instance_ce); if (!(is_a & SPL_IS_A_FORWARD)) { diff --git a/ext/spl/tests/array_access_ex.phpt b/ext/spl/tests/array_access_ex.phpt deleted file mode 100755 index ed7aceab19..0000000000 --- a/ext/spl/tests/array_access_ex.phpt +++ /dev/null @@ -1,154 +0,0 @@ ---TEST-- -SPL: array_access ---SKIPIF-- - ---FILE-- -obj = &$obj; - $this->idx = $index; - } - - function set($value) { - echo __METHOD__ . "($value,".$this->idx.")\n"; - return $this->obj->set($this->idx, $value); - } -} - -class c implements spl_array_access_ex { - - public $a = array('1st', 1, 2=>'3rd', '4th'=>4); - - function new_writer($index) { - return new array_write(&$this, $index); - } - - function exists($index) { - echo __METHOD__ . "($index)\n"; - return array_key_exists($index, $this->a); - } - - function get($index) { - echo __METHOD__ . "($index)\n"; - return $this->a[$index]; - } - - function set($index, $newval) { - echo __METHOD__ . "($index,$newval)\n"; - return $this->a[$index] = $newval; - } -} - -$obj = new c(); - -var_dump($obj->a); - -var_dump($obj[0]); -var_dump($obj[1]); -var_dump($obj[2]); -var_dump($obj['4th']); -var_dump($obj['5th']); -var_dump($obj[6]); - -echo "WRITE 1\n"; -$obj[1] = 'Changed 1'; -var_dump($obj[1]); -echo "WRITE 2\n"; -$obj['4th'] = 'Changed 4th'; -var_dump($obj['4th']); -echo "WRITE 3\n"; -$obj['5th'] = 'Added 5th'; -var_dump($obj['5th']); -echo "WRITE 4\n"; -$obj[6] = 'Added 6'; -var_dump($obj[6]); - -var_dump($obj[0]); -var_dump($obj[2]); - -$x = $obj[6] = 'changed 6'; -var_dump($obj[6]); -var_dump($x); - -print "Done\n"; -?> ---EXPECTF-- -array(4) { - [0]=> - string(3) "1st" - [1]=> - int(1) - [2]=> - string(3) "3rd" - ["4th"]=> - int(4) -} -c::exists(0) -c::get(0) -string(3) "1st" -c::exists(1) -c::get(1) -int(1) -c::exists(2) -c::get(2) -string(3) "3rd" -c::exists(4th) -c::get(4th) -int(4) -c::exists(5th) - -Notice: Undefined index: 5th in %sarray_access_ex.php on line %d -NULL -c::exists(6) - -Notice: Undefined index: 6 in %sarray_access_ex.php on line %d -NULL -WRITE 1 -c::exists(1) -array_write::set(Changed 1,1) -c::set(1,Changed 1) -c::exists(1) -c::get(1) -string(9) "Changed 1" -WRITE 2 -c::exists(4th) -array_write::set(Changed 4th,4th) -c::set(4th,Changed 4th) -c::exists(4th) -c::get(4th) -string(11) "Changed 4th" -WRITE 3 -c::exists(5th) -array_write::set(Added 5th,5th) -c::set(5th,Added 5th) -c::exists(5th) -c::get(5th) -string(9) "Added 5th" -WRITE 4 -c::exists(6) -array_write::set(Added 6,6) -c::set(6,Added 6) -c::exists(6) -c::get(6) -string(7) "Added 6" -c::exists(0) -c::get(0) -string(3) "1st" -c::exists(2) -c::get(2) -string(3) "3rd" -c::exists(6) -array_write::set(changed 6,6) -c::set(6,changed 6) -c::exists(6) -c::get(6) -string(9) "changed 6" -string(9) "changed 6" -Done -- 2.40.0