]> granicus.if.org Git - php/commitdiff
Use better data structures (incomplete)
authorDmitry Stogov <dmitry@zend.com>
Fri, 14 Feb 2014 13:48:45 +0000 (17:48 +0400)
committerDmitry Stogov <dmitry@zend.com>
Fri, 14 Feb 2014 13:48:45 +0000 (17:48 +0400)
Zend/zend.c
Zend/zend.h
Zend/zend_API.c
Zend/zend_builtin_functions.c
Zend/zend_exceptions.c
Zend/zend_execute_API.c
Zend/zend_objects.c
Zend/zend_objects_API.h
Zend/zend_variables.c
Zend/zend_vm_def.h

index fed9ebb34a795c5b439c6d79f69c417646ae7777..92c938a5df272a67ccc875db3f08bb517c639638 100644 (file)
@@ -260,15 +260,7 @@ ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_cop
                                if (Z_OBJ_HANDLER_P(expr, cast_object)) {
                                        zval val;
 
-//???                                  ALLOC_ZVAL(val);
-//???                                  INIT_PZVAL_COPY(val, expr);
-//???                                  zval_copy_ctor(val);
-                                       if (Z_ISREF_P(expr)) {
-                                               ZVAL_COPY_VALUE(&val, Z_REFVAL_P(expr));
-                                       } else {
-                                               ZVAL_COPY_VALUE(&val, expr);
-                                       }
-                                       zval_copy_ctor(&val);
+                                       ZVAL_DUP_DEREF(&val, expr);
                                        if (Z_OBJ_HANDLER_P(expr, cast_object)(&val, expr_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
                                                zval_ptr_dtor(&val);
                                                break;
@@ -624,9 +616,6 @@ static zend_bool php_auto_globals_create_globals(zend_string *name TSRMLS_DC) /*
 {
        zval globals;
 
-//???  ALLOC_ZVAL(globals);
-//???  Z_SET_REFCOUNT_P(globals, 1);
-//???  Z_SET_ISREF_P(globals);
        ZVAL_ARR(&globals, &EG(symbol_table));
        ZVAL_NEW_REF(&globals, &globals);
        zend_hash_update(&EG(symbol_table).ht, name, &globals);
@@ -1315,10 +1304,10 @@ ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval *retval, int file_cou
                                        if (call_user_function_ex(CG(function_table), NULL, &orig_user_exception_handler, &retval2, 1, params, 1, NULL TSRMLS_CC) == SUCCESS) {
                                                zval_ptr_dtor(&retval2);
                                                if (EG(exception)) {
-//???                                                  zval_ptr_dtor(&EG(exception));
+                                                       OBJ_RELEASE(EG(exception));
                                                        EG(exception) = NULL;
                                                }
-//???                                          zval_ptr_dtor(&old_exception);
+                                               OBJ_RELEASE(old_exception);
                                        } else {
                                                EG(exception) = old_exception;
                                                zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
index bf7f0d599ae8b255eaed3919c64c566717df9664..eb771866b58f08a553808cb96a912267f3949ccf 100644 (file)
@@ -662,6 +662,16 @@ END_EXTERN_C()
                zval_copy_ctor(z);                                              \
        } while (0)
 
+#define ZVAL_DUP_DEREF(z, v)                                   \
+       do {                                                                            \
+               if (Z_ISREF_P(v)) {                                             \
+                       ZVAL_COPY_VALUE(z, Z_REFVAL_P(v));      \
+               } else {                                                                \
+                       ZVAL_COPY_VALUE(z, v);                          \
+               }                                                                               \
+               zval_copy_ctor(z);                                              \
+       } while (0)
+
 #define INIT_PZVAL_COPY(z, v)                                  \
        do {                                                                            \
                ZVAL_COPY_VALUE(z, v);                                  \
index 356147d91283587ef9625b08276aa32d079b3090..26db975bc5a1abf9b14588367e5e3e49975fc9d9 100644 (file)
@@ -3720,8 +3720,6 @@ ZEND_API int zend_update_static_property(zend_class_entry *scope, const char *na
                                ZVAL_COPY_VALUE(property, value);
                                if (Z_REFCOUNT_P(value) > 0) {
                                        zval_copy_ctor(property);
-//???                          } else {
-//???                                  efree(value);
                                }
                        } else {
                                zval garbage;
index 8139a443f70fbfa6f8a0cbbef0af66db114ec692..c35a10217178b1d2f01cb18aa334616aaf9f32da 100644 (file)
@@ -923,8 +923,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
                }
 
                /* copy: enforce read only access */
-               ZVAL_DUP(&prop_copy, prop);
-//???          INIT_PZVAL(prop_copy);
+               ZVAL_DUP_DEREF(&prop_copy, prop);
 
                /* this is necessary to make it able to work with default array
                 * properties, returned to user */
@@ -1938,8 +1937,7 @@ ZEND_FUNCTION(get_defined_constants)
                                add_assoc_zval(return_value, module_names[module_number], &modules[module_number]);
                        }
 
-                       ZVAL_DUP(&const_val, &val->value);
-//???                  INIT_PZVAL(const_val);
+                       ZVAL_DUP_DEREF(&const_val, &val->value);
 
                        add_assoc_zval_ex(&modules[module_number], val->name->val, val->name->len, &const_val);
 next_constant:
@@ -2019,8 +2017,6 @@ ZEND_FUNCTION(debug_print_backtrace)
        ptr = ptr->prev_execute_data;
 
        while (ptr && (limit == 0 || frameno < limit)) {
-//???          const char *free_class_name = NULL;
-
                frameno++;
                class_name = NULL;
                call_type = NULL;   
@@ -2149,9 +2145,6 @@ ZEND_FUNCTION(debug_print_backtrace)
                include_filename = filename;
                ptr = skip->prev_execute_data;
                ++indent;
-//???          if (free_class_name) {
-//???                  efree((char*)free_class_name);
-//???          }
        }
 }
 
index 938f885d0b6af3e5b5443b9f9f8c83e43ab3e512..4e1a2b6d591490ad7af84f3bf61f7860378b847c 100644 (file)
@@ -133,13 +133,13 @@ ZEND_API void zend_clear_exception(TSRMLS_D) /* {{{ */
 {
        if (EG(prev_exception)) {
                                
-//???          zval_ptr_dtor(&EG(prev_exception));
+               OBJ_RELEASE(EG(prev_exception));
                EG(prev_exception) = NULL;
        }
        if (!EG(exception)) {
                return;
        }
-//???  zval_ptr_dtor(&EG(exception));
+       OBJ_RELEASE(EG(exception));
        EG(exception) = NULL;
        EG(current_execute_data)->opline = EG(opline_before_exception);
 #if ZEND_DEBUG
@@ -269,8 +269,7 @@ static void _default_exception_get_entry(zval *object, char *name, int name_len,
 
        value = zend_read_property(default_exception_ce, object, name, name_len, 0 TSRMLS_CC);
 
-       ZVAL_DUP(return_value, value);
-//???  INIT_PZVAL(return_value);
+       ZVAL_DUP_DEREF(return_value, value);
 }
 /* }}} */
 
@@ -580,7 +579,7 @@ int zend_spprintf(char **message, int max_len, const char *format, ...) /* {{{ *
    Obtain the string representation of the Exception object */
 ZEND_METHOD(exception, __toString)
 {
-       zval message, file, line, *trace, *exception;
+       zval message, file, line, trace, *exception;
        char *str, *prev_str;
        int len = 0;
        zend_fcall_info fci;
@@ -608,27 +607,27 @@ ZEND_METHOD(exception, __toString)
                ZVAL_COPY_VALUE(&fci.function_name, &fname);
                fci.symbol_table = NULL;
                fci.object_ptr = exception;
-//???          fci.retval_ptr_ptr = &trace;
+               fci.retval = &trace;
                fci.param_count = 0;
                fci.params = NULL;
                fci.no_separation = 1;
 
                zend_call_function(&fci, NULL TSRMLS_CC);
 
-//???          if (Z_TYPE_P(trace) != IS_STRING) {
-//???                  zval_ptr_dtor(&trace);
-//???                  trace = NULL;
-//???          }
+               if (Z_TYPE(trace) != IS_STRING) {
+                       zval_ptr_dtor(&trace);
+                       ZVAL_UNDEF(&trace);
+               }
 
                if (Z_STRLEN(message) > 0) {
                        len = zend_spprintf(&str, 0, "exception '%s' with message '%s' in %s:%ld\nStack trace:\n%s%s%s",
                                                                Z_OBJCE_P(exception)->name, Z_STRVAL(message), Z_STRVAL(file), Z_LVAL(line),
-                                                               (trace && Z_STRLEN_P(trace)) ? Z_STRVAL_P(trace) : "#0 {main}\n",
+                                                               (Z_TYPE(trace) == IS_STRING && Z_STRLEN(trace)) ? Z_STRVAL(trace) : "#0 {main}\n",
                                                                len ? "\n\nNext " : "", prev_str);
                } else {
                        len = zend_spprintf(&str, 0, "exception '%s' in %s:%ld\nStack trace:\n%s%s%s",
                                                                Z_OBJCE_P(exception)->name, Z_STRVAL(file), Z_LVAL(line),
-                                                               (trace && Z_STRLEN_P(trace)) ? Z_STRVAL_P(trace) : "#0 {main}\n",
+                                                               (Z_TYPE(trace) == IS_STRING && Z_STRLEN(trace)) ? Z_STRVAL(trace) : "#0 {main}\n",
                                                                len ? "\n\nNext " : "", prev_str);
                }
                efree(prev_str);
@@ -638,9 +637,7 @@ ZEND_METHOD(exception, __toString)
 
                exception = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 0 TSRMLS_CC);
 
-//???          if (trace) {
-//???                  zval_ptr_dtor(&trace);
-//???          }
+               zval_ptr_dtor(&trace);
 
        }
        zval_dtor(&fname);
index 0e95e8f8f58b9fc3a6ea4cc79115a859370a9f9a..7176c1f147d2f8ef766f5a82622d460890d0d6d0 100644 (file)
@@ -429,11 +429,13 @@ ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ *
        Z_DELREF_P(zval_ptr);
        if (Z_REFCOUNT_P(zval_ptr) == 0) {
                zval_internal_dtor(zval_ptr);
-       } else if (Z_REFCOUNT_P(zval_ptr) == 1) {
+       } else if (Z_REFCOUNT_P(zval_ptr) == 1) {               
 //???          Z_UNSET_ISREF_P(zval_ptr);
-               zend_reference *ref = Z_REF_P(zval_ptr);
-               ZVAL_COPY_VALUE(zval_ptr, Z_REFVAL_P(zval_ptr));
-               efree(ref);
+               if (Z_ISREF_P(zval_ptr)) {
+                       zend_reference *ref = Z_REF_P(zval_ptr);
+                       ZVAL_COPY_VALUE(zval_ptr, Z_REFVAL_P(zval_ptr));
+                       efree(ref);
+               }
        }
 }
 /* }}} */
@@ -472,7 +474,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope
                zend_error(E_ERROR, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p));
        } else if ((Z_TYPE_P(p) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
                int refcount;
-//???          zend_uchar is_ref;
+               zend_uchar is_ref;
 
                SEPARATE_ZVAL_IF_NOT_REF(p);
 
@@ -485,17 +487,21 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope
                        char *actual = Z_STRVAL_P(p);
 
                        if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) {
+                               int len;
+
                                zend_error(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(p));
-                               Z_STRLEN_P(p) -= ((colon - Z_STRVAL_P(p)) + 1);
-//???                          if (inline_change) {
-                                       zend_string *tmp = STR_INIT(colon, Z_STRLEN_P(p), 0);
+                               len = Z_STRLEN_P(p) - ((colon - Z_STRVAL_P(p)) + 1);
+                               if (inline_change) {
+                                       zend_string *tmp = STR_INIT(colon + 1, len, 0);
                                        STR_RELEASE(Z_STR_P(p));
                                        Z_STR_P(p) = tmp;
-//???                          } else {
+                               } else {
 //???                                  Z_STRVAL_P(p) = colon + 1;
-//???                          }
+                                       Z_STR_P(p) = STR_INIT(colon + 1, len, 0);
+                               }
                        } else {
-                               char *save = actual, *slash;
+                               zend_string *save = Z_STR_P(p);
+                               char *slash;
                                int actual_len = Z_STRLEN_P(p);
                                if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) && (slash = (char *)zend_memrchr(actual, '\\', actual_len))) {
                                        actual = slash + 1;
@@ -516,23 +522,19 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope
                                        --actual_len;
                                }
                                if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) {
-                                       int fix_save = 0;
-                                       if (save[0] == '\\') {
-                                               save++;
-                                               fix_save = 1;
+                                       if (save->val[0] == '\\') {
+                                               zend_error(E_ERROR, "Undefined constant '%s'", save->val + 1);
+                                       } else {
+                                               zend_error(E_ERROR, "Undefined constant '%s'", save->val);
                                        }
-                                       zend_error(E_ERROR, "Undefined constant '%s'", save);
-                                       if (fix_save) {
-                                               save--;
+                                       if (inline_change) {
+                                               STR_RELEASE(save);
                                        }
-//???                                  if (inline_change) {
-//???                                          str_efree(save);
-//???                                  }
                                        save = NULL;
                                }
-//???                          if (inline_change && save && save != actual) {
-//???                                  str_efree(save);
-//???                          }
+                               if (inline_change && save && save->val != actual) {
+                                       STR_RELEASE(save);
+                               }
                                zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",  actual,  actual);
                                p->type = IS_STRING;
                                if (!inline_change) {
@@ -540,9 +542,9 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope
                                }
                        }
                } else {
-//???                  if (inline_change) {
-//???                          str_efree(Z_STRVAL_P(p));
-//???                  }
+                       if (inline_change) {
+                               STR_RELEASE(Z_STR_P(p));
+                       }
                        *p = const_value;
                }
 
@@ -608,7 +610,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope
                                        }
                                        zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",     str_index, str_index);
                                }
-                               ZVAL_STRINGL(&const_value, str_index, str_index_len-3, 1);
+                               ZVAL_STRINGL(&const_value, str_index, str_index_len-3);
                        }
 #endif
 
@@ -881,19 +883,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
                if ((EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)) {
                        ZVAL_UNDEF(&EG(This));
                } else {
-                       ZVAL_COPY_VALUE(&EG(This), fci->object_ptr);
-
-                       if (!Z_ISREF(EG(This))) {
-                               Z_ADDREF(EG(This)); /* For $this pointer */
-                       } else {
-//???                          zval *this_ptr;
-//???
-//???                          ALLOC_ZVAL(this_ptr);
-//???                          *this_ptr = *EG(This);
-//???                          INIT_PZVAL(this_ptr);
-//???                          zval_copy_ctor(this_ptr);
-//???                          EG(This) = this_ptr;
-                       }
+                       ZVAL_COPY(&EG(This), fci->object_ptr);
                }
        } else {
                ZVAL_UNDEF(&EG(This));
index cf7ac3fa6ce618e3178a9b6d215bb97b6e9bc017..1f30477a59e7cc91a4156d8d19ddb5eddba4cd04 100644 (file)
@@ -144,12 +144,8 @@ ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *o
        int i;
 
        for (i = 0; i < old_object->ce->default_properties_count; i++) {
-//???          if (!new_object->properties) {
-                       zval_ptr_dtor(&new_object->properties_table[i]);
-//???          }
-//???          if (!old_object->properties) {
-                       ZVAL_COPY(&new_object->properties_table[i], &old_object->properties_table[i]);
-//???          }
+               zval_ptr_dtor(&new_object->properties_table[i]);
+               ZVAL_COPY(&new_object->properties_table[i], &old_object->properties_table[i]);
        }
        if (old_object->properties) {
                if (!new_object->properties) {
index 3119ee99326d3616b26f3d3de30763fe417a318e..0695d68c7c6b86ed1a0a913530f10c64f81ab157 100644 (file)
                (o) = (zend_object*)((((zend_uintptr_t)(n)) << 1) | FREE_BUCKET); \
        } while (0)
 
+
+#define OBJ_RELEASE(obj) do { \
+               zend_object *_obj = (obj); \
+               if (--_obj->gc.refcount == 0) { \
+                               zend_objects_store_del(_obj TSRMLS_CC); \
+               } \
+       } while (0)
+
 typedef struct _zend_objects_store {
        zend_object **object_buckets;
        zend_uint top;
index 799d8e49a3ea32751e07ed6e4ce18d8c963cd1b4..6c4076a4e42e938d89de0be8ee8ac19b571f18de 100644 (file)
@@ -55,9 +55,7 @@ ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC)
                        {
                                TSRMLS_FETCH();
 
-                               if (Z_DELREF_P(zvalue) == 0) {
-                                       zend_objects_store_del(Z_OBJ_P(zvalue) TSRMLS_CC);
-                               }
+                               OBJ_RELEASE(Z_OBJ_P(zvalue));
                        }
                        break;
                case IS_RESOURCE:
index b52ef6abacffd8de6975ec0ac38dd7e06ef97277..2cf7e5268bd41fb0f48fb2668296446498794f5b 100644 (file)
@@ -978,9 +978,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST|
        varname = GET_OP1_ZVAL_PTR(BP_VAR_R);
 
        if (OP1_TYPE != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
-               ZVAL_DUP(&tmp_varname, varname);
-//???          Z_SET_REFCOUNT(tmp_varname, 1);
-//???          Z_UNSET_ISREF(tmp_varname);
+               ZVAL_DUP_DEREF(&tmp_varname, varname);
                convert_to_string(&tmp_varname);
                varname = &tmp_varname;
        }