]> granicus.if.org Git - php/commitdiff
Update and remove parts no longer possible
authorMarcus Boerger <helly@php.net>
Wed, 16 Jul 2003 09:48:36 +0000 (09:48 +0000)
committerMarcus Boerger <helly@php.net>
Wed, 16 Jul 2003 09:48:36 +0000 (09:48 +0000)
ext/spl/php_spl.c
ext/spl/php_spl.h
ext/spl/spl.php
ext/spl/spl_array.c
ext/spl/spl_array.h
ext/spl/spl_engine.c
ext/spl/spl_engine.h
ext/spl/spl_foreach.c
ext/spl/tests/array_access_ex.phpt [deleted file]

index fb8593f2a5955cac874763f43d7c8dc2922ccf71..c8a086672695fb1a6216e864c38efbb512bac278 100755 (executable)
@@ -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
 }
 /* }}} */
 
index 3ae3b636dabc04431a824ff89a667ded7e4f0bf6..e4abfd45144e66cda1afde2f3e951e5f4d098339 100755 (executable)
@@ -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);
index 5e21888dd3711b71d59af534c0698553c9362df3..e52a15a214d7bc4a32de0ad838753ed31190967c 100755 (executable)
@@ -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
index 5a6c034f6adb38202a8a1481a5c244687aba6f3a..87a081a9e612310a0271d992c28940e231f12086 100755 (executable)
 #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
 /* }}} */
index 2b75753a3124a41d0ae081d44826041c9df83066..3aa194c8cc01e84faaed77941d52afb62d1fc04a 100755 (executable)
@@ -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 */
 
 /*
index 692be6d0945791aa29b3bb09ac3c67a5dfc58c3b..35d233c7d10871c81d38c8455871efbe9c7c0702 100755 (executable)
@@ -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;
index e20ea39bb68c27850a3a33a6faa0cd6bf6a0799f..f3a16472e5e6aa8c2fa7c3a6342d74d688afb485 100755 (executable)
@@ -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);
index 9466a0ad1e917abeea53c3ff406a4f0368d7f817..35414f478b813ec6349aa1ad1597c05a469f732c 100755 (executable)
@@ -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 (executable)
index ed7acea..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
---TEST--
-SPL: array_access
---SKIPIF--
-<?php
-       if (!extension_loaded("spl")) die("skip");
-       if (!in_array("spl_array_access", spl_classes())) die("skip spl_array_access not present");
-?>
---FILE--
-<?php
-class array_write implements spl_array_writer {
-       private $obj;
-       private $idx;
-
-       function __construct(&$obj, $index = null) {
-               $this->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