diff options
author | Zeev Suraski <zeev@php.net> | 1999-12-31 13:56:59 +0000 |
---|---|---|
committer | Zeev Suraski <zeev@php.net> | 1999-12-31 13:56:59 +0000 |
commit | f2d703e916e767e86c2d6434e809f29f6906f5fc (patch) | |
tree | d15df1e02c73ceac0b796190be44e48f0b537b42 | |
parent | 400ee6caa0353d8b32797dad345be6da1dd07e2f (diff) | |
download | php-git-f2d703e916e767e86c2d6434e809f29f6906f5fc.tar.gz |
- Nuke undefined_variable_string
- Introduce IS_UNSET
-rw-r--r-- | Zend/zend-parser.y | 5 | ||||
-rw-r--r-- | Zend/zend-scanner.l | 4 | ||||
-rw-r--r-- | Zend/zend.c | 7 | ||||
-rw-r--r-- | Zend/zend.h | 11 | ||||
-rw-r--r-- | Zend/zend_API.c | 32 | ||||
-rw-r--r-- | Zend/zend_API.h | 15 | ||||
-rw-r--r-- | Zend/zend_builtin_functions.c | 1 | ||||
-rw-r--r-- | Zend/zend_compile.c | 4 | ||||
-rw-r--r-- | Zend/zend_constants.c | 15 | ||||
-rw-r--r-- | Zend/zend_execute.c | 62 | ||||
-rw-r--r-- | Zend/zend_execute_API.c | 3 | ||||
-rw-r--r-- | Zend/zend_operators.c | 58 | ||||
-rw-r--r-- | Zend/zend_operators.h | 1 | ||||
-rw-r--r-- | Zend/zend_variables.c | 14 |
14 files changed, 149 insertions, 83 deletions
diff --git a/Zend/zend-parser.y b/Zend/zend-parser.y index 378ab4f276..246a988385 100644 --- a/Zend/zend-parser.y +++ b/Zend/zend-parser.y @@ -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; } diff --git a/Zend/zend-scanner.l b/Zend/zend-scanner.l index fea3149a79..42d9c90c85 100644 --- a/Zend/zend-scanner.l +++ b/Zend/zend-scanner.l @@ -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; } diff --git a/Zend/zend.c b/Zend/zend.c index 2aa5cbb0d1..5297d8ef9a 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -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; diff --git a/Zend/zend.h b/Zend/zend.h index b066b47e12..dff61e48d9 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -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); \ diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 3ec6fac259..6822e299b2 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -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; diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 36d1c95469..8079b5be8d 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -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; \ diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 22fe6b1b0c..2303316450 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -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"); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 45e6c5372e..66176f2c72 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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; diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index 1aec33130d..69d08c3428 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -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); } } diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 2087252d17..156a139cd5 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -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 **) ¶m 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; diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 88662d3b1e..7bcd211e96 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -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: diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 11064c0087..b4a007c60c 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -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; diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index 727d1c9d21..a4378305b8 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -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); diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index f2cb9a1388..71a9861345 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -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; } } |