diff options
Diffstat (limited to 'Zend/zend_variables.c')
| -rw-r--r-- | Zend/zend_variables.c | 167 | 
1 files changed, 167 insertions, 0 deletions
diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c new file mode 100644 index 0000000000..a4365435d7 --- /dev/null +++ b/Zend/zend_variables.c @@ -0,0 +1,167 @@ +/* +   +----------------------------------------------------------------------+ +   | Zend Engine                                                          | +   +----------------------------------------------------------------------+ +   | Copyright (c) 1998, 1999 Andi Gutmans, Zeev Suraski                  | +   +----------------------------------------------------------------------+ +   | This source file is subject to the Zend license, that is bundled     | +   | with this package in the file LICENSE.  If you did not receive a     | +   | copy of the Zend license, please mail us at zend@zend.com so we can  | +   | send you a copy immediately.                                         | +   +----------------------------------------------------------------------+ +   | Authors: Andi Gutmans <andi@zend.com>                                | +   |          Zeev Suraski <zeev@zend.com>                                | +   +----------------------------------------------------------------------+ +*/ + +#include <stdio.h> +#include "zend.h" +#include "zend_API.h" +#include "zend_globals.h" +#include "zend_constants.h" +#include "zend_variables.h" +#include "zend_list.h" + +ZEND_API char *empty_string = "";	/* in order to save emalloc() and efree() time for +									 * empty strings (usually used to denote empty +									 * return values in failed functions). +									 * 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) +{ +	var->type = IS_STRING; +	var->value.str.val = empty_string; +	var->value.str.len = 0; +} + +ZEND_API inline void var_uninit(zval *var) +{ +	var->type = IS_STRING; +	var->value.str.val = undefined_variable_string; +	var->value.str.len = 0; +} +		 + +ZEND_API void zval_dtor(zval *zvalue) +{ +	if (zvalue->type==IS_LONG) { +		return; +	} +	switch(zvalue->type) { +		case IS_STRING: +		case IS_CONSTANT: +			STR_FREE(zvalue->value.str.val); +			break; +		case IS_ARRAY: { +				ELS_FETCH(); + +				if (zvalue->value.ht && (zvalue->value.ht != &EG(symbol_table))) { +					if (EG(AiCount)==0) { +						zend_hash_destroy(zvalue->value.ht); +						efree(zvalue->value.ht); +					} else { +						zend_ptr_stack_push(&EG(garbage), zvalue->value.ht); +					} +				} +			} +			break; +		case IS_OBJECT: { +				ELS_FETCH(); + +				if (EG(AiCount)==0) { +					zend_hash_destroy(zvalue->value.obj.properties); +					efree(zvalue->value.obj.properties); +				} else { +					zend_ptr_stack_push(&EG(garbage), zvalue->value.obj.properties); +				} +			} +			break; +		case IS_RESOURCE: +			/* destroy resource */ +			zend_list_delete(zvalue->value.lval); +			break; +		case IS_LONG: +		case IS_DOUBLE: +		case IS_BOOL: +		default: +			return; +			break; +	} +} + + +void zval_add_ref(zval **p) +{ +	(*p)->refcount++; +} + + + + +ZEND_API int zval_copy_ctor(zval *zvalue) +{ +	switch (zvalue->type) { +		case IS_RESOURCE: +			zend_list_addref(zvalue->value.lval); +			break; +		case IS_BOOL: +		case IS_LONG: +			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; +					} +					return SUCCESS; +				} +			} +			zvalue->value.str.val = (char *) estrndup(zvalue->value.str.val, zvalue->value.str.len); +			break; +		case IS_ARRAY: { +				zval *tmp; +				HashTable *original_ht = zvalue->value.ht; +				ELS_FETCH(); + +				if (!zvalue->value.ht || zvalue->value.ht==&EG(symbol_table)) { +					var_reset(zvalue); +					return FAILURE; +				} +				zvalue->value.ht = (HashTable *) emalloc(sizeof(HashTable)); +				zend_hash_init(zvalue->value.ht, 0, NULL, PVAL_PTR_DTOR, 0); +				zend_hash_copy(zvalue->value.ht, original_ht, (void (*)(void *)) zval_add_ref, (void *) &tmp, sizeof(zval *)); +			} +			break; +		case IS_OBJECT: { +				zval *tmp; +				HashTable *original_ht = zvalue->value.obj.properties; + +				zvalue->value.obj.properties = (HashTable *) emalloc(sizeof(HashTable)); +				zend_hash_init(zvalue->value.obj.properties, 0, NULL, PVAL_PTR_DTOR, 0); +				zend_hash_copy(zvalue->value.obj.properties, original_ht, (void (*)(void *)) zval_add_ref, (void *) &tmp, sizeof(zval *)); +			} +			break; +	} +	return SUCCESS; +} + + +ZEND_API int zend_print_variable(zval *var)  +{ +	return zend_print_zval(var, 0); +} + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + */  | 
