]> granicus.if.org Git - php/commitdiff
- Nuke undefined_variable_string
authorZeev Suraski <zeev@php.net>
Fri, 31 Dec 1999 13:56:59 +0000 (13:56 +0000)
committerZeev Suraski <zeev@php.net>
Fri, 31 Dec 1999 13:56:59 +0000 (13:56 +0000)
- Introduce IS_UNSET

14 files changed:
Zend/zend-parser.y
Zend/zend-scanner.l
Zend/zend.c
Zend/zend.h
Zend/zend_API.c
Zend/zend_API.h
Zend/zend_builtin_functions.c
Zend/zend_compile.c
Zend/zend_constants.c
Zend/zend_execute.c
Zend/zend_execute_API.c
Zend/zend_operators.c
Zend/zend_operators.h
Zend/zend_variables.c

index 378ab4f276731d0777e7f26cae2b07984bc92223..246a988385311ae57f05d0cf0bf747fde91deed4 100644 (file)
@@ -67,7 +67,7 @@
 %left T_SL T_SR
 %left '+' '-' '.'
 %left '*' '/' '%'
-%right '!' '~' T_INC T_DEC T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_ARRAY_CAST T_OBJECT_CAST T_BOOL_CAST '@'
+%right '!' '~' T_INC T_DEC T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_ARRAY_CAST T_OBJECT_CAST T_BOOL_CAST T_UNSET_CAST '@'
 %right '['
 %nonassoc T_NEW
 %token T_EXIT
@@ -294,12 +294,10 @@ non_empty_parameter_list:
        |       '&' T_VARIABLE                                  { znode tmp;  fetch_simple_variable(&tmp, &$2, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_FORCE CLS_CC); }
        |       T_CONST T_VARIABLE                      { znode tmp;  fetch_simple_variable(&tmp, &$2, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
        |       T_VARIABLE '=' static_scalar            { znode tmp;  fetch_simple_variable(&tmp, &$1, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$3, BYREF_NONE CLS_CC); }
-       |       T_VARIABLE '=' T_UNSET          { znode tmp;  fetch_simple_variable(&tmp, &$1, 0 CLS_CC); $$.op_type = IS_CONST; $$.u.constant.value.lval=1; $$.u.constant.type=IS_LONG; INIT_PZVAL(&$$.u.constant); do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
        |       non_empty_parameter_list ',' T_VARIABLE                                                 { znode tmp;  fetch_simple_variable(&tmp, &$3, 0 CLS_CC); $$=$1; $$.u.constant.value.lval++; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
        |       non_empty_parameter_list ',' '&' T_VARIABLE                                     { znode tmp;  fetch_simple_variable(&tmp, &$4, 0 CLS_CC); $$=$1; $$.u.constant.value.lval++; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_FORCE CLS_CC); }
        |       non_empty_parameter_list ',' T_CONST T_VARIABLE                 { znode tmp;  fetch_simple_variable(&tmp, &$4, 0 CLS_CC); $$=$1; $$.u.constant.value.lval++; do_receive_arg(ZEND_RECV, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
        |       non_empty_parameter_list ',' T_VARIABLE '=' static_scalar       { znode tmp;  fetch_simple_variable(&tmp, &$3, 0 CLS_CC); $$=$1; $$.u.constant.value.lval++; do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, &$5, BYREF_NONE CLS_CC); }
-       |       non_empty_parameter_list ',' T_VARIABLE '=' T_UNSET             { znode tmp;  fetch_simple_variable(&tmp, &$3, 0 CLS_CC); $$=$1; $$.u.constant.value.lval++; do_receive_arg(ZEND_RECV_INIT, &tmp, &$$, NULL, BYREF_NONE CLS_CC); }
 ;
 
 
@@ -444,6 +442,7 @@ expr_without_variable:
        |       T_ARRAY_CAST expr       { do_cast(&$$, &$2, IS_ARRAY CLS_CC); }
        |       T_OBJECT_CAST expr      { do_cast(&$$, &$2, IS_OBJECT CLS_CC); }
        |       T_BOOL_CAST expr        { do_cast(&$$, &$2, IS_BOOL CLS_CC); }
+       |       T_UNSET_CAST expr       { do_cast(&$$, &$2, IS_UNSET CLS_CC); }
        |       T_EXIT exit_expr        { do_exit(&$$, &$2 CLS_CC); }
        |       '@' { do_begin_silence(&$1 CLS_CC); } expr { do_end_silence(&$1 CLS_CC); $$ = $3; }
        |       scalar                          { $$ = $1; }
index fea3149a79b4c764d1b8afa4343d9ae9e1a89616..42d9c90c85f872829f48a6ade612d465c27546cf 100644 (file)
@@ -879,6 +879,10 @@ ESCAPED_AND_WHITESPACE [\n\t\r #'.:;,()|^&+-/*=%!~<>?@]+
        return T_BOOL_CAST;
 }
 
+<ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("unset"){TABS_AND_SPACES}")" {
+       return T_UNSET_CAST;
+}
+
 <ST_IN_SCRIPTING>"eval" {
        return T_EVAL;
 }
index 2aa5cbb0d1db90ff39d69f98cd635c9860c776f5..5297d8ef9aa7303f1e402f971ececcee6518a988 100644 (file)
@@ -117,6 +117,9 @@ ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_cop
                return;
        }
        switch (expr->type) {
+               case IS_UNSET:
+                       expr_copy->value.str.len = 0;
+                       expr_copy->value.str.val = empty_string;
                case IS_BOOL:
 #if 1
                        if (expr->value.lval) {
@@ -336,9 +339,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions)
        /* This zval can be used to initialize allocate zval's to an uninit'ed value */
        zval_used_for_init.is_ref = 0;
        zval_used_for_init.refcount = 1;
-       zval_used_for_init.type = IS_STRING;
-       zval_used_for_init.value.str.val = undefined_variable_string;
-       zval_used_for_init.value.str.len = 0;
+       zval_used_for_init.type = IS_UNSET;
 
 #ifdef ZTS
        global_constants_table = NULL;
index b066b47e12f32f0abf20e97a43cfb032be636163..dff61e48d97c4433a7ebdad3aa4a49c644664c3c 100644 (file)
@@ -199,8 +199,12 @@ typedef struct _zend_utility_values {
 #undef MAX
 #define MAX(a,b)  (((a)>(b))?(a):(b))
 #define MIN(a,b)  (((a)<(b))?(a):(b))
+#define ZEND_STRL(str)         (str), (sizeof(str)-1)
+#define ZEND_STRS(str)         (str), (sizeof(str)
+
 
 /* data types */
+#define IS_UNSET       0
 #define IS_LONG                1
 #define IS_DOUBLE      2
 #define IS_STRING      3
@@ -226,13 +230,12 @@ ZEND_API int zend_print_zval(zval *expr, int indent);
 ZEND_API void zend_print_zval_r(zval *expr, int indent);
 
 ZEND_API extern char *empty_string;
-ZEND_API extern char *undefined_variable_string;
 
-#define STR_FREE(ptr) if (ptr && ptr!=empty_string && ptr!=undefined_variable_string) { efree(ptr); }
-#define STR_FREE_REL(ptr) if (ptr && ptr!=empty_string && ptr!=undefined_variable_string) { efree_rel(ptr); }
+#define STR_FREE(ptr) if (ptr && ptr!=empty_string) { efree(ptr); }
+#define STR_FREE_REL(ptr) if (ptr && ptr!=empty_string) { efree_rel(ptr); }
 
 #define STR_REALLOC(ptr, size)                                                                         \
-       if (ptr!=empty_string && ptr!=undefined_variable_string) {              \
+       if (ptr!=empty_string) {                                                                                \
                ptr = (char *) erealloc(ptr, size);                                                     \
        } else {                                                                                                                \
                ptr = (char *) emalloc(size);                                                           \
index 3ec6fac2595d12adb4e0e43c78c9ef756d86ba9f..6822e299b2f002b0dbe3052b348773ce60b60418 100644 (file)
@@ -242,6 +242,16 @@ ZEND_API inline int add_assoc_long(zval *arg, char *key, long n)
 }
 
 
+ZEND_API inline int add_assoc_unset(zval *arg, char *key)
+{
+       zval *tmp;
+
+       ALLOC_ZVAL(tmp);
+       tmp->type = IS_UNSET;
+       INIT_PZVAL(tmp);
+       return zend_hash_update(arg->value.ht, key, strlen(key)+1, (void *) &tmp, sizeof(zval *), NULL);
+}
+
 ZEND_API inline int add_assoc_bool(zval *arg, char *key, int b)
 {
        zval *tmp;
@@ -324,6 +334,17 @@ ZEND_API inline int add_index_long(zval *arg, uint index, long n)
 }
 
 
+ZEND_API inline int add_index_unset(zval *arg, uint index)
+{
+       zval *tmp;
+
+       ALLOC_ZVAL(tmp);
+       tmp->type = IS_UNSET;
+       INIT_PZVAL(tmp);
+       return zend_hash_index_update(arg->value.ht, index, (void *) &tmp, sizeof(zval *), NULL);
+}
+
+
 ZEND_API inline int add_index_bool(zval *arg, uint index, int b)
 {
        zval *tmp;
@@ -406,6 +427,17 @@ ZEND_API inline int add_next_index_long(zval *arg, long n)
 }
 
 
+ZEND_API inline int add_next_index_unset(zval *arg)
+{
+       zval *tmp;
+
+       ALLOC_ZVAL(tmp);
+       tmp->type = IS_UNSET;
+       INIT_PZVAL(tmp);
+       return zend_hash_next_index_insert(arg->value.ht, &tmp, sizeof(zval *), NULL);
+}
+
+
 ZEND_API inline int add_next_index_bool(zval *arg, int b)
 {
        zval *tmp;
index 36d1c9546961ed67951f12af815a978fe11cf8cd..8079b5be8d37f0cdc3ac94f8697993a49908908f 100644 (file)
@@ -98,6 +98,7 @@ ZEND_API int object_init_ex(zval *arg, zend_class_entry *ce);
 ZEND_API int add_assoc_function(zval *arg, char *key,void (*function_ptr)(INTERNAL_FUNCTION_PARAMETERS));
 
 ZEND_API int add_assoc_long(zval *arg, char *key, long n);
+ZEND_API int add_assoc_unset(zval *arg, char *key);
 ZEND_API int add_assoc_bool(zval *arg, char *key, int b);
 ZEND_API int add_assoc_resource(zval *arg, char *key, int r);
 ZEND_API int add_assoc_double(zval *arg, char *key, double d);
@@ -105,6 +106,7 @@ ZEND_API int add_assoc_string(zval *arg, char *key, char *str, int duplicate);
 ZEND_API int add_assoc_stringl(zval *arg, char *key, char *str, uint length, int duplicate);
 
 ZEND_API int add_index_long(zval *arg, uint idx, long n);
+ZEND_API int add_index_unset(zval *arg, uint idx);
 ZEND_API int add_index_bool(zval *arg, uint idx, int b);
 ZEND_API int add_index_resource(zval *arg, uint idx, int r);
 ZEND_API int add_index_double(zval *arg, uint idx, double d);
@@ -112,6 +114,7 @@ ZEND_API int add_index_string(zval *arg, uint idx, char *str, int duplicate);
 ZEND_API int add_index_stringl(zval *arg, uint idx, char *str, uint length, int duplicate);
 
 ZEND_API int add_next_index_long(zval *arg, long n);
+ZEND_API int add_next_index_unset(zval *arg);
 ZEND_API int add_next_index_bool(zval *arg, int b);
 ZEND_API int add_next_index_resource(zval *arg, int r);
 ZEND_API int add_next_index_double(zval *arg, double d);
@@ -147,6 +150,9 @@ ZEND_API int zend_set_hash_symbol(zval *symbol, char *name, int name_length,
                return_value->type = IS_BOOL;   \
                return_value->value.lval = b;   \
        }
+#define RETVAL_UNSET() {                               \
+               return_value->type = IS_UNSET;  \
+       }
 #define RETVAL_LONG(l) {                               \
                return_value->type = IS_LONG;   \
                return_value->value.lval = l;   \
@@ -183,6 +189,11 @@ ZEND_API int zend_set_hash_symbol(zval *symbol, char *name, int name_length,
                return;                                                 \
        }
 
+#define RETURN_UNSET() {                               \
+               return_value->type = IS_UNSET;  \
+               return;                                                 \
+       }
+
 #define RETURN_LONG(l) {                               \
                return_value->type = IS_LONG;   \
                return_value->value.lval = l;   \
@@ -211,10 +222,6 @@ ZEND_API int zend_set_hash_symbol(zval *symbol, char *name, int name_length,
 #define RETURN_FALSE  { RETVAL_FALSE; return; }
 #define RETURN_TRUE   { RETVAL_TRUE; return; }
 
-#define RETURN_SQLNULL RETURN_LONG(0)
-#define RETVAL_SQLNULL RETVAL_LONG(0)
-#define IS_SQLNULL(p) ((p)->type==IS_LONG && ((p)->value.lval == 0))
-
 #define SET_VAR_STRING(n,v)    {                                                                                                                                                               \
                                                                {                                                                                                                                                       \
                                                                        zval *var;                                                                                                                              \
index 22fe6b1b0c907b67a724af558e762248e66ec6de..2303316450050895dfde8b77dda4aa97009a0ef1 100644 (file)
@@ -325,6 +325,7 @@ ZEND_FUNCTION(define)
                case IS_STRING:
                case IS_BOOL:
                case IS_RESOURCE:
+               case IS_UNSET:
                        break;
                default:
                        zend_error(E_WARNING,"Constants may only evaluate to scalar values");
index 45e6c5372e5aade93d2923845853c57e8eeb6d7d..66176f2c72cc608a2398d0befb51420ed7e30fa8 100644 (file)
@@ -741,10 +741,8 @@ void do_receive_arg(int op, znode *var, znode *offset, znode *initialization, un
        opline->opcode = op;
        opline->result = *var;
        opline->op1 = *offset;
-       if ((op == ZEND_RECV_INIT) && initialization) {
+       if ((op == ZEND_RECV_INIT)) {
                opline->op2 = *initialization;
-       } else {
-               SET_UNUSED(opline->op2);
        }
        if (pass_type==BYREF_FORCE && !CG(active_op_array)->arg_types) {
                int i;
index 1aec33130d51fb597cbada003a8803defc610c1b..69d08c34281491595400652b4368c56d8f3a74e5 100644 (file)
@@ -118,22 +118,21 @@ void zend_register_standard_constants(ELS_D)
                c.flags = CONST_PERSISTENT;
                c.module_number = 0;
 
-               c.name = zend_strndup("TRUE",4);
-               c.name_len = 5;
+               c.name = zend_strndup(ZEND_STRL("TRUE"));
+               c.name_len = sizeof("TRUE");
                c.value.value.lval = 1;
                c.value.type = IS_BOOL;
                zend_register_constant(&c ELS_CC);
                
-               c.name = zend_strndup("FALSE",5);
-               c.name_len = 6;
+               c.name = zend_strndup(ZEND_STRL("FALSE"));
+               c.name_len = sizeof("FALSE");
                c.value.value.lval = 0;
                c.value.type = IS_BOOL;
                zend_register_constant(&c ELS_CC);
 
-               c.name = zend_strndup("SQL_NULL",8);
-               c.name_len = 9;
-               c.value.value.lval = 0;
-               c.value.type = IS_LONG;
+               c.name = zend_strndup(ZEND_STRL("NULL"));
+               c.name_len = sizeof("NULL");
+               c.value.type = IS_UNSET;
                zend_register_constant(&c ELS_CC);
        }
 }
index 2087252d17f845b56266e2a4b3e3fb56bde8a40b..156a139cd5dacbd6873ab9f3355b9a6fe9d492ed 100644 (file)
@@ -656,7 +656,7 @@ static inline void zend_fetch_dimension_address(znode *result, znode *op1, znode
                return;
        }
 
-       if (container->type == IS_STRING && container->value.str.len==0) {
+       if (container->type == IS_UNSET) {
                switch (type) {
                        case BP_VAR_RW:
                        case BP_VAR_W:
@@ -695,36 +695,35 @@ static inline void zend_fetch_dimension_address(znode *result, znode *op1, znode
                        SEPARATE_ON_READ_OBJECT(*retval, type);
                        SELECTIVE_PZVAL_LOCK(**retval, result);
                        break;
+               case IS_UNSET:
+                       /* for read-mode only */
+                       *retval = &EG(uninitialized_zval_ptr);
+                       SELECTIVE_PZVAL_LOCK(**retval, result);
+                       FREE_OP(op2, free_op2);
+                       break;
                case IS_STRING: {
                                zval *offset;
-                               offset = get_zval_ptr(op2, Ts, &free_op2, BP_VAR_R);
+                               zval tmp;
 
-                               if (container->value.str.val == undefined_variable_string) {
-                                       /* for read-mode only */
-                                       *retval = &EG(uninitialized_zval_ptr);
-                                       SELECTIVE_PZVAL_LOCK(**retval, result);
-                                       FREE_OP(op2, free_op2);
-                               } else {
-                                       zval tmp;
+                               offset = get_zval_ptr(op2, Ts, &free_op2, BP_VAR_R);
 
-                                       if (offset->type != IS_LONG) {
-                                               tmp = *offset;
-                                               zval_copy_ctor(&tmp);
-                                               convert_to_long(&tmp);
-                                               offset = &tmp;
-                                       }
-                                       if (!container->is_ref && type!=BP_VAR_R && type!=BP_VAR_IS) {
-                                               SEPARATE_ZVAL(container_ptr);
-                                       }
-                                       container = *container_ptr;
-                                       Ts[result->u.var].EA.str = container;
-                                       PZVAL_LOCK(container);
-                                       Ts[result->u.var].EA.offset = offset->value.lval;
-                                       Ts[result->u.var].EA.type = IS_STRING_OFFSET;
-                                       FREE_OP(op2, free_op2);
-                                       *retval = NULL;
-                                       return;
+                               if (offset->type != IS_LONG) {
+                                       tmp = *offset;
+                                       zval_copy_ctor(&tmp);
+                                       convert_to_long(&tmp);
+                                       offset = &tmp;
+                               }
+                               if (!container->is_ref && type!=BP_VAR_R && type!=BP_VAR_IS) {
+                                       SEPARATE_ZVAL(container_ptr);
                                }
+                               container = *container_ptr;
+                               Ts[result->u.var].EA.str = container;
+                               PZVAL_LOCK(container);
+                               Ts[result->u.var].EA.offset = offset->value.lval;
+                               Ts[result->u.var].EA.type = IS_STRING_OFFSET;
+                               FREE_OP(op2, free_op2);
+                               *retval = NULL;
+                               return;
                        }
                        break;
                default: {
@@ -1720,12 +1719,6 @@ send_by_ref:
                                        zval **param, *assignment_value;
 
                                        if (zend_ptr_stack_get_arg(opline->op1.u.constant.value.lval, (void **) &param ELS_CC)==FAILURE) {
-                                               if (opline->op2.op_type == IS_UNUSED) {
-                                                       if (opline->result.op_type == IS_VAR) {
-                                                               PZVAL_UNLOCK(*Ts[opline->result.u.var].var.ptr_ptr);
-                                                       }
-                                                       break;
-                                               }
                                                if (opline->op2.u.constant.type == IS_CONSTANT) {
                                                        zval *default_value;
                                                        zval tmp;
@@ -1949,6 +1942,9 @@ send_by_ref:
                                                zendi_zval_copy_ctor(*result);
                                        }                                       
                                        switch (opline->op2.u.constant.type) {
+                                               case IS_UNSET:
+                                                       convert_to_unset(result);
+                                                       break;
                                                case IS_BOOL:
                                                        convert_to_boolean(result);
                                                        break;
@@ -2161,7 +2157,7 @@ send_by_ref:
                                                        isset = 1;
                                                }
                                        } else if (*var==EG(uninitialized_zval_ptr)
-                                               || ((*var)->type == IS_STRING && (*var)->value.str.val == undefined_variable_string)) {
+                                               || ((*var)->type == IS_UNSET)) {
                                                isset = 0;
                                        } else {
                                                isset = 1;
index 88662d3b1e745c13f547ea3acb8c07229ba6bb59..7bcd211e96ef0970c1d184053d4c4538fca73745 100644 (file)
@@ -225,6 +225,9 @@ ZEND_API inline int i_zend_is_true(zval *op)
        int result;
 
        switch (op->type) {
+               case IS_UNSET:
+                       result = 0;
+                       break;
                case IS_LONG:
                case IS_BOOL:
                case IS_RESOURCE:
index 11064c0087d0005490aa4324a6d375c54c135317..b4a007c60cd3cb040bd2aa8cdcc391a8f7e34045 100644 (file)
@@ -45,9 +45,6 @@ ZEND_API void convert_scalar_to_number(zval *op)
                        case IS_DOUBLE:
                        case IS_LONG:
                                break;
-                       case IS_BOOL:
-                               op->type = IS_LONG;
-                               break;
 #if WITH_BCMATH
                        case IS_BC:
                                op->type = IS_DOUBLE; /* may have lost significant digits */
@@ -61,6 +58,9 @@ ZEND_API void convert_scalar_to_number(zval *op)
                STR_FREE(strval);
        } else if (op->type==IS_BOOL || op->type==IS_RESOURCE) {
                op->type = IS_LONG;
+       } else if (op->type==IS_UNSET) {
+               op->type = IS_LONG;
+               op->value.lval = 0;
        }
 }
 
@@ -85,6 +85,9 @@ ZEND_API void convert_scalar_to_number(zval *op)
                (holder).value.lval = (op)->value.lval;                                         \
                (holder).type = IS_LONG;                                                                        \
                (op) = &(holder);                                                                                       \
+       } else if ((op)->type==IS_UNSET) {                                                              \
+               (holder).type = IS_UNSET;                                                                       \
+               (op) = &(holder);                                                                                       \
        }
 
 
@@ -98,6 +101,9 @@ ZEND_API void convert_scalar_to_number(zval *op)
                (op) = &(holder);                                                                                       \
        } else if ((op)->type != IS_LONG) {                                                             \
                switch ((op)->type) {                                                                           \
+                       case IS_UNSET:                                                                                  \
+                               (holder).value.lval = 0;                                                        \
+                               break;                                                                                          \
                        case IS_DOUBLE:                                                                                 \
                                (holder).value.lval = (long) (op)->value.dval;          \
                                break;                                                                                          \
@@ -125,6 +131,9 @@ ZEND_API void convert_scalar_to_number(zval *op)
                convert_to_boolean(op);                                                                         \
        } else if ((op)->type != IS_BOOL) {                                                             \
                switch ((op)->type) {                                                                           \
+                       case IS_UNSET:                                                                                  \
+                               (holder).value.lval = 0;                                                        \
+                               break;                                                                                          \
                        case IS_RESOURCE:                                                                               \
                        case IS_LONG:                                                                                   \
                                (holder).value.lval = ((op)->value.lval ? 1 : 0);       \
@@ -167,6 +176,9 @@ ZEND_API void convert_to_long_base(zval *op, int base)
        long tmp;
 
        switch (op->type) {
+               case IS_UNSET:
+                       op->value.lval = 0;
+                       break;
                case IS_RESOURCE:
                case IS_BOOL:
                case IS_LONG:
@@ -206,11 +218,13 @@ ZEND_API void convert_to_double(zval *op)
        double tmp;
 
        switch (op->type) {
+               case IS_UNSET:
+                       op->value.dval = 0.0;
+                       break;
                case IS_RESOURCE:
                case IS_BOOL:
                case IS_LONG:
                        op->value.dval = (double) op->value.lval;
-                       op->type = IS_DOUBLE;
                        break;
                case IS_DOUBLE:
                        break;
@@ -218,28 +232,32 @@ ZEND_API void convert_to_double(zval *op)
                        strval = op->value.str.val;
 
                        op->value.dval = strtod(strval, NULL);
-                       op->type = IS_DOUBLE;
                        STR_FREE(strval);
                        break;
                case IS_ARRAY:
                        tmp = (zend_hash_num_elements(op->value.ht)?1:0);
                        zval_dtor(op);
                        op->value.dval = tmp;
-                       op->type = IS_DOUBLE;
                        break;
                case IS_OBJECT:
                        tmp = (zend_hash_num_elements(op->value.obj.properties)?1:0);
                        zval_dtor(op);
                        op->value.dval = tmp;
-                       op->type = IS_DOUBLE;
                        break;                  
                default:
                        zend_error(E_WARNING, "Cannot convert to real value (type=%d)", op->type);
                        zval_dtor(op);
                        op->value.dval = 0;
-                       op->type = IS_DOUBLE;
                        break;
        }
+       op->type = IS_DOUBLE;
+}
+
+
+ZEND_API void convert_to_unset(zval *op)
+{
+       zval_dtor(op);
+       op->type = IS_UNSET;
 }
 
 
@@ -251,6 +269,9 @@ ZEND_API void convert_to_boolean(zval *op)
        switch (op->type) {
                case IS_BOOL:
                        break;
+               case IS_UNSET:
+                       op->value.lval = 0;
+                       break;
                case IS_RESOURCE:
                case IS_LONG:
                        op->value.lval = (op->value.lval ? 1 : 0);
@@ -295,6 +316,10 @@ ZEND_API void convert_to_string(zval *op)
        ELS_FETCH();
 
        switch (op->type) {
+               case IS_UNSET:
+                       op->value.str.val = empty_string;
+                       op->value.str.len = 0;
+                       break;
                case IS_STRING:
                        break;
                case IS_BOOL:
@@ -893,6 +918,7 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2)
                result->value.lval = op1->value.lval - op2->value.lval;
                return SUCCESS;
        }
+
        zendi_convert_scalar_to_number(op1, op1_copy, result);
        zendi_convert_scalar_to_number(op2, op2_copy, result);
 
@@ -924,6 +950,10 @@ ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2)
                return SUCCESS;
        }
        switch (op1->type) {
+               case IS_UNSET:
+                       result->value.lval = (op2->type==IS_UNSET);
+                       return SUCCESS;
+                       break;
                case IS_BOOL:
                case IS_LONG:
                case IS_RESOURCE:
@@ -1120,14 +1150,12 @@ ZEND_API int increment_function(zval *op1)
                case IS_DOUBLE:
                        op1->value.dval = op1->value.dval + 1;
                        break;
+               case IS_UNSET:
+                       op1->value.lval = 1;
+                       op1->type = IS_LONG;
+                       break;
                case IS_STRING: /* Perl style string increment */
-                       if (op1->value.str.len==0) { /* consider as 0 */
-                               STR_FREE(op1->value.str.val);
-                               op1->value.lval = 1;
-                               op1->type = IS_LONG;
-                       } else {
-                               increment_string(op1);
-                       }
+                       increment_string(op1);
                        break;
                default:
                        return FAILURE;
index 727d1c9d21feace283cdfe6cff499fe14141990c..a4378305b8b85fe122c61c22135a380e3d619b26 100644 (file)
@@ -56,6 +56,7 @@ ZEND_API void convert_scalar_to_number(zval *op);
 ZEND_API void convert_to_string(zval *op);
 ZEND_API void convert_to_long(zval *op);
 ZEND_API void convert_to_long_base(zval *op, int base);
+ZEND_API void convert_to_unset(zval *op);
 ZEND_API void convert_to_boolean(zval *op);
 ZEND_API void convert_to_array(zval *op);
 ZEND_API void convert_to_object(zval *op);
index f2cb9a138877f01bc8feabac5ceef6094ff4ef38..71a98613452ac9e75e133d2caa9f355917ad9044 100644 (file)
@@ -32,8 +32,6 @@ ZEND_API char *empty_string = "";     /* in order to save emalloc() and efree() time
                                                                         * The macro STR_FREE() will not efree() it.
                                                                         */
 
-ZEND_API char *undefined_variable_string = "\0";
-
 /* this function MUST set the value for the variable to an empty string */
 /* and empty strings must be evaluated as FALSE */
 ZEND_API inline void var_reset(zval *var)
@@ -50,9 +48,7 @@ ZEND_API inline void var_reset(zval *var)
 
 ZEND_API inline void var_uninit(zval *var)
 {
-       var->type = IS_STRING;
-       var->value.str.val = undefined_variable_string;
-       var->value.str.len = 0;
+       var->type = IS_UNSET;
 }
                
 
@@ -86,6 +82,7 @@ ZEND_API int _zval_dtor(zval *zvalue ZEND_FILE_LINE_DC)
                case IS_LONG:
                case IS_DOUBLE:
                case IS_BOOL:
+               case IS_UNSET:
                default:
                        return 1;
                        break;
@@ -118,15 +115,12 @@ ZEND_API int _zval_copy_ctor(zval *zvalue ZEND_FILE_LINE_DC)
                        break;
                case IS_BOOL:
                case IS_LONG:
+               case IS_UNSET:
                        break;
                case IS_STRING:
                        if (zvalue->value.str.val) {
                                if (zvalue->value.str.len==0) {
-                                       if (zvalue->value.str.val==undefined_variable_string) {
-                                               zvalue->value.str.val = undefined_variable_string;
-                                       } else {
-                                               zvalue->value.str.val = empty_string;
-                                       }
+                                       zvalue->value.str.val = empty_string;
                                        return SUCCESS;
                                }
                        }