Use better data structures (incomplete)

This commit is contained in:
Dmitry Stogov 2014-02-10 10:04:30 +04:00
parent 89a9acea1f
commit f4cfaf36e2
145 changed files with 21353 additions and 23867 deletions

View file

@ -123,8 +123,6 @@ static HashTable *global_persistent_list = NULL;
ZEND_API zend_utility_values zend_uv;
ZEND_API zval zval_used_for_init; /* True global variable */
/* version information */
static char *zend_version_info;
static uint zend_version_info_length;
@ -133,11 +131,10 @@ static uint zend_version_info_length;
static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent, zend_bool is_object TSRMLS_DC) /* {{{ */
{
zval **tmp;
char *string_key;
zval *tmp;
zend_string *string_key;
HashPosition iterator;
ulong num_key;
uint str_len;
int i;
for (i = 0; i < indent; i++) {
@ -146,17 +143,17 @@ static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent,
ZEND_PUTS_EX("(\n");
indent += PRINT_ZVAL_INDENT;
zend_hash_internal_pointer_reset_ex(ht, &iterator);
while (zend_hash_get_current_data_ex(ht, (void **) &tmp, &iterator) == SUCCESS) {
while ((tmp = zend_hash_get_current_data_ex(ht, &iterator)) != NULL) {
for (i = 0; i < indent; i++) {
ZEND_PUTS_EX(" ");
}
ZEND_PUTS_EX("[");
switch (zend_hash_get_current_key_ex(ht, &string_key, &str_len, &num_key, 0, &iterator)) {
switch (zend_hash_get_current_key_ex(ht, &string_key, &num_key, 0, &iterator)) {
case HASH_KEY_IS_STRING:
if (is_object) {
const char *prop_name, *class_name;
int prop_len;
int mangled = zend_unmangle_property_name_ex(string_key, str_len - 1, &class_name, &prop_name, &prop_len);
int mangled = zend_unmangle_property_name_ex(string_key->val, string_key->len, &class_name, &prop_name, &prop_len);
ZEND_WRITE_EX(prop_name, prop_len);
if (class_name && mangled == SUCCESS) {
@ -169,7 +166,7 @@ static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent,
}
}
} else {
ZEND_WRITE_EX(string_key, str_len-1);
ZEND_WRITE_EX(string_key->val, string_key->len);
}
break;
case HASH_KEY_IS_LONG:
@ -181,7 +178,7 @@ static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent,
break;
}
ZEND_PUTS_EX("] => ");
zend_print_zval_r_ex(write_func, *tmp, indent+PRINT_ZVAL_INDENT TSRMLS_CC);
zend_print_zval_r_ex(write_func, tmp, indent+PRINT_ZVAL_INDENT TSRMLS_CC);
ZEND_PUTS_EX("\n");
zend_hash_move_forward_ex(ht, &iterator);
}
@ -195,29 +192,28 @@ static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent,
static void print_flat_hash(HashTable *ht TSRMLS_DC) /* {{{ */
{
zval **tmp;
char *string_key;
zval *tmp;
zend_string *string_key;
HashPosition iterator;
ulong num_key;
uint str_len;
int i = 0;
zend_hash_internal_pointer_reset_ex(ht, &iterator);
while (zend_hash_get_current_data_ex(ht, (void **) &tmp, &iterator) == SUCCESS) {
while ((tmp = zend_hash_get_current_data_ex(ht, &iterator)) != NULL) {
if (i++ > 0) {
ZEND_PUTS(",");
}
ZEND_PUTS("[");
switch (zend_hash_get_current_key_ex(ht, &string_key, &str_len, &num_key, 0, &iterator)) {
switch (zend_hash_get_current_key_ex(ht, &string_key, &num_key, 0, &iterator)) {
case HASH_KEY_IS_STRING:
ZEND_PUTS(string_key);
ZEND_WRITE(string_key->val, string_key->len);
break;
case HASH_KEY_IS_LONG:
zend_printf("%ld", num_key);
break;
}
ZEND_PUTS("] => ");
zend_print_flat_zval_r(*tmp TSRMLS_CC);
zend_print_flat_zval_r(tmp TSRMLS_CC);
zend_hash_move_forward_ex(ht, &iterator);
}
}
@ -231,26 +227,28 @@ ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_cop
}
switch (Z_TYPE_P(expr)) {
case IS_NULL:
Z_STRLEN_P(expr_copy) = 0;
Z_STRVAL_P(expr_copy) = STR_EMPTY_ALLOC();
Z_STR_P(expr_copy) = STR_EMPTY_ALLOC();
break;
case IS_BOOL:
if (Z_LVAL_P(expr)) {
Z_STRLEN_P(expr_copy) = 1;
Z_STRVAL_P(expr_copy) = estrndup("1", 1);
// TODO: ??? use interned string
Z_STR_P(expr_copy) = STR_INIT("1", 1, 0);
} else {
Z_STRLEN_P(expr_copy) = 0;
Z_STRVAL_P(expr_copy) = STR_EMPTY_ALLOC();
Z_STR_P(expr_copy) = STR_EMPTY_ALLOC();
}
break;
case IS_RESOURCE:
Z_STRVAL_P(expr_copy) = (char *) emalloc(sizeof("Resource id #") - 1 + MAX_LENGTH_OF_LONG);
Z_STRLEN_P(expr_copy) = snprintf(Z_STRVAL_P(expr_copy), sizeof("Resource id #") - 1 + MAX_LENGTH_OF_LONG, "Resource id #%ld", Z_LVAL_P(expr));
case IS_RESOURCE: {
char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG];
int len;
len = snprintf(buf, sizeof(buf), "Resource id #%ld", Z_RES_HANDLE_P(expr));
Z_STR_P(expr_copy) = STR_INIT(buf, len, 0);
}
break;
case IS_ARRAY:
zend_error(E_NOTICE, "Array to string conversion");
Z_STRLEN_P(expr_copy) = sizeof("Array") - 1;
Z_STRVAL_P(expr_copy) = estrndup("Array", Z_STRLEN_P(expr_copy));
// TODO: ??? use interned string
Z_STR_P(expr_copy) = STR_INIT("Array", 1, 0);
break;
case IS_OBJECT:
{
@ -260,12 +258,18 @@ ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_cop
break;
}
if (Z_OBJ_HANDLER_P(expr, cast_object)) {
zval *val;
zval val;
ALLOC_ZVAL(val);
INIT_PZVAL_COPY(val, expr);
zval_copy_ctor(val);
if (Z_OBJ_HANDLER_P(expr, cast_object)(val, expr_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
//??? 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);
if (Z_OBJ_HANDLER_P(expr, cast_object)(&val, expr_copy, IS_STRING TSRMLS_CC) == SUCCESS) {
zval_ptr_dtor(&val);
break;
}
@ -278,28 +282,25 @@ ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_cop
if (Z_TYPE_P(z) != IS_OBJECT) {
zend_make_printable_zval(z, expr_copy, use_copy);
if (*use_copy) {
zval_ptr_dtor(&z);
zval_ptr_dtor(z);
} else {
ZVAL_ZVAL(expr_copy, z, 0, 1);
*use_copy = 1;
}
return;
}
zval_ptr_dtor(&z);
zval_ptr_dtor(z);
}
zend_error(EG(exception) ? E_ERROR : E_RECOVERABLE_ERROR, "Object of class %s could not be converted to string", Z_OBJCE_P(expr)->name);
Z_STRLEN_P(expr_copy) = 0;
Z_STRVAL_P(expr_copy) = STR_EMPTY_ALLOC();
zend_error(EG(exception) ? E_ERROR : E_RECOVERABLE_ERROR, "Object of class %s could not be converted to string", Z_OBJCE_P(expr)->name->val);
Z_STR_P(expr_copy) = STR_EMPTY_ALLOC();
}
break;
case IS_DOUBLE:
*expr_copy = *expr;
zval_copy_ctor(expr_copy);
ZVAL_DUP(expr_copy, expr);
zend_locale_sprintf_double(expr_copy ZEND_FILE_LINE_CC);
break;
default:
*expr_copy = *expr;
zval_copy_ctor(expr_copy);
ZVAL_DUP(expr_copy, expr);
convert_to_string(expr_copy);
break;
}
@ -354,14 +355,13 @@ ZEND_API void zend_print_flat_zval_r(zval *expr TSRMLS_DC) /* {{{ */
case IS_OBJECT:
{
HashTable *properties = NULL;
const char *class_name = NULL;
zend_uint clen;
zend_string *class_name = NULL;
if (Z_OBJ_HANDLER_P(expr, get_class_name)) {
Z_OBJ_HANDLER_P(expr, get_class_name)(expr, &class_name, &clen, 0 TSRMLS_CC);
class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(expr, 0 TSRMLS_CC);
}
if (class_name) {
zend_printf("%s Object (", class_name);
zend_printf("%s Object (", class_name->val);
} else {
zend_printf("%s Object (", "Unknown Class");
}
@ -412,15 +412,14 @@ ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int
case IS_OBJECT:
{
HashTable *properties;
const char *class_name = NULL;
zend_uint clen;
zend_string *class_name = NULL;
int is_temp;
if (Z_OBJ_HANDLER_P(expr, get_class_name)) {
Z_OBJ_HANDLER_P(expr, get_class_name)(expr, &class_name, &clen, 0 TSRMLS_CC);
class_name = Z_OBJ_HANDLER_P(expr, get_class_name)(expr, 0 TSRMLS_CC);
}
if (class_name) {
ZEND_PUTS_EX(class_name);
ZEND_PUTS_EX(class_name->val);
} else {
ZEND_PUTS_EX("Unknown Class");
}
@ -621,16 +620,16 @@ static void php_scanner_globals_ctor(zend_php_scanner_globals *scanner_globals_p
void zend_init_opcodes_handlers(void);
static zend_bool php_auto_globals_create_globals(const char *name, uint name_len TSRMLS_DC) /* {{{ */
static zend_bool php_auto_globals_create_globals(zend_string *name TSRMLS_DC) /* {{{ */
{
zval *globals;
zval globals;
ALLOC_ZVAL(globals);
Z_SET_REFCOUNT_P(globals, 1);
Z_SET_ISREF_P(globals);
Z_TYPE_P(globals) = IS_ARRAY;
Z_ARRVAL_P(globals) = &EG(symbol_table);
zend_hash_update(&EG(symbol_table), name, name_len + 1, &globals, sizeof(zval *), NULL);
//??? 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);
return 0;
}
/* }}} */
@ -712,11 +711,6 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions TS
zend_hash_init_ex(&module_registry, 50, NULL, ZEND_MODULE_DTOR, 1, 0);
zend_init_rsrc_list_dtors();
/* This zval can be used to initialize allocate zval's to an uninit'ed value */
Z_UNSET_ISREF(zval_used_for_init);
Z_SET_REFCOUNT(zval_used_for_init, 1);
Z_TYPE(zval_used_for_init) = IS_NULL;
#ifdef ZTS
ts_allocate_id(&compiler_globals_id, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor);
ts_allocate_id(&executor_globals_id, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor);
@ -740,14 +734,14 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions TS
ini_scanner_globals_ctor(&ini_scanner_globals TSRMLS_CC);
php_scanner_globals_ctor(&language_scanner_globals TSRMLS_CC);
zend_set_default_compile_time_values(TSRMLS_C);
EG(user_error_handler) = NULL;
EG(user_exception_handler) = NULL;
ZVAL_UNDEF(&EG(user_error_handler));
ZVAL_UNDEF(&EG(user_exception_handler));
#endif
zend_interned_strings_init(TSRMLS_C);
zend_startup_builtin_functions(TSRMLS_C);
zend_register_standard_constants(TSRMLS_C);
zend_register_auto_global("GLOBALS", sizeof("GLOBALS") - 1, 1, php_auto_globals_create_globals TSRMLS_CC);
zend_register_auto_global(STR_INIT("GLOBALS", sizeof("GLOBALS") - 1, 0), 1, php_auto_globals_create_globals TSRMLS_CC);
#ifndef ZTS
zend_init_rsrc_plist(TSRMLS_C);
@ -1019,14 +1013,15 @@ ZEND_API int zend_get_configuration_directive(const char *name, uint name_length
ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
{
char *str;
int len;
va_list args;
va_list usr_copy;
zval ***params;
zval *retval;
zval *z_error_type, *z_error_message, *z_error_filename, *z_error_lineno, *z_context;
zval params[5];
zval retval;
const char *error_filename;
uint error_lineno;
zval *orig_user_error_handler;
zval orig_user_error_handler;
zend_bool in_compilation;
zend_class_entry *saved_class_entry;
zend_stack bp_stack;
@ -1083,7 +1078,7 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
case E_USER_DEPRECATED:
case E_RECOVERABLE_ERROR:
if (zend_is_compiling(TSRMLS_C)) {
error_filename = zend_get_compiled_filename(TSRMLS_C);
error_filename = zend_get_compiled_filename(TSRMLS_C)->val;
error_lineno = zend_get_compiled_lineno(TSRMLS_C);
} else if (zend_is_executing(TSRMLS_C)) {
error_filename = zend_get_executed_filename(TSRMLS_C);
@ -1116,7 +1111,7 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
va_start(args, format);
/* if we don't have a user defined error handler */
if (!EG(user_error_handler)
if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF
|| !(EG(user_error_handler_error_reporting) & type)
|| EG(error_handling) != EH_NORMAL) {
zend_error_cb(type, error_filename, error_lineno, format, args);
@ -1132,12 +1127,6 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
break;
default:
/* Handle the error in user space */
ALLOC_INIT_ZVAL(z_error_message);
ALLOC_INIT_ZVAL(z_error_type);
ALLOC_INIT_ZVAL(z_error_filename);
ALLOC_INIT_ZVAL(z_error_lineno);
ALLOC_INIT_ZVAL(z_context);
/* va_copy() is __va_copy() in old gcc versions.
* According to the autoconf manual, using
* memcpy(&dst, &src, sizeof(va_list))
@ -1150,21 +1139,22 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
# endif
#endif
va_copy(usr_copy, args);
Z_STRLEN_P(z_error_message) = zend_vspprintf(&Z_STRVAL_P(z_error_message), 0, format, usr_copy);
len = zend_vspprintf(&str, 0, format, usr_copy);
ZVAL_STR(&params[1], STR_INIT(str, len, 0));
efree(str);
#ifdef va_copy
va_end(usr_copy);
#endif
Z_TYPE_P(z_error_message) = IS_STRING;
Z_LVAL_P(z_error_type) = type;
Z_TYPE_P(z_error_type) = IS_LONG;
ZVAL_LONG(&params[0], type);
if (error_filename) {
ZVAL_STRING(z_error_filename, error_filename, 1);
ZVAL_STRING(&params[2], error_filename);
} else {
ZVAL_NULL(&params[2]);
}
Z_LVAL_P(z_error_lineno) = error_lineno;
Z_TYPE_P(z_error_lineno) = IS_LONG;
ZVAL_LONG(&params[3], error_lineno);
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
@ -1172,22 +1162,14 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
/* during shutdown the symbol table table can be still null */
if (!EG(active_symbol_table)) {
Z_TYPE_P(z_context) = IS_NULL;
ZVAL_NULL(&params[4]);
} else {
Z_ARRVAL_P(z_context) = EG(active_symbol_table);
Z_TYPE_P(z_context) = IS_ARRAY;
zval_copy_ctor(z_context);
//??? ZVAL_ARR(&params[4], EG(active_symbol_table));
zval_copy_ctor(&params[4]);
}
params = (zval ***) emalloc(sizeof(zval **)*5);
params[0] = &z_error_type;
params[1] = &z_error_message;
params[2] = &z_error_filename;
params[3] = &z_error_lineno;
params[4] = &z_context;
orig_user_error_handler = EG(user_error_handler);
EG(user_error_handler) = NULL;
ZVAL_COPY_VALUE(&orig_user_error_handler, &EG(user_error_handler));
ZVAL_UNDEF(&EG(user_error_handler));
/* User error handler may include() additinal PHP files.
* If an error was generated during comilation PHP will compile
@ -1209,9 +1191,10 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
CG(in_compilation) = 0;
}
if (call_user_function_ex(CG(function_table), NULL, orig_user_error_handler, &retval, 5, params, 1, NULL TSRMLS_CC) == SUCCESS) {
if (retval) {
if (Z_TYPE_P(retval) == IS_BOOL && Z_LVAL_P(retval) == 0) {
ZVAL_UNDEF(&retval);
if (call_user_function_ex(CG(function_table), NULL, &orig_user_error_handler, &retval, 5, params, 1, NULL TSRMLS_CC) == SUCCESS) {
if (Z_TYPE(retval) != IS_UNDEF) {
if (Z_TYPE(retval) == IS_BOOL && Z_LVAL(retval) == 0) {
zend_error_cb(type, error_filename, error_lineno, format, args);
}
zval_ptr_dtor(&retval);
@ -1234,19 +1217,12 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
CG(in_compilation) = 1;
}
if (!EG(user_error_handler)) {
EG(user_error_handler) = orig_user_error_handler;
if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF) {
ZVAL_COPY_VALUE(&EG(user_error_handler), &orig_user_error_handler);
}
else {
zval_ptr_dtor(&orig_user_error_handler);
}
efree(params);
zval_ptr_dtor(&z_error_message);
zval_ptr_dtor(&z_error_type);
zval_ptr_dtor(&z_error_filename);
zval_ptr_dtor(&z_error_lineno);
zval_ptr_dtor(&z_context);
break;
}
@ -1295,13 +1271,13 @@ ZEND_API void zend_output_debug_string(zend_bool trigger_break, const char *form
}
/* }}} */
ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_count, ...) /* {{{ */
ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval *retval, int file_count, ...) /* {{{ */
{
va_list files;
int i;
zend_file_handle *file_handle;
zend_op_array *orig_op_array = EG(active_op_array);
zval **orig_retval_ptr_ptr = EG(return_value_ptr_ptr);
//??? zval **orig_retval_ptr_ptr = EG(return_value_ptr_ptr);
long orig_interactive = CG(interactive);
va_start(files, file_count);
@ -1321,31 +1297,30 @@ ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_co
EG(active_op_array) = zend_compile_file(file_handle, type TSRMLS_CC);
if (file_handle->opened_path) {
int dummy = 1;
zend_hash_add(&EG(included_files), file_handle->opened_path, strlen(file_handle->opened_path) + 1, (void *)&dummy, sizeof(int), NULL);
zend_hash_str_add_empty_element(&EG(included_files), file_handle->opened_path, strlen(file_handle->opened_path));
}
zend_destroy_file_handle(file_handle TSRMLS_CC);
if (EG(active_op_array)) {
EG(return_value_ptr_ptr) = retval ? retval : NULL;
//??? EG(return_value_ptr_ptr) = retval ? retval : NULL;
zend_execute(EG(active_op_array) TSRMLS_CC);
zend_exception_restore(TSRMLS_C);
if (EG(exception)) {
if (EG(user_exception_handler)) {
zval *orig_user_exception_handler;
zval **params[1], *retval2, *old_exception;
if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
zval orig_user_exception_handler;
zval params[1], retval2;
zend_object *old_exception;
old_exception = EG(exception);
EG(exception) = NULL;
params[0] = &old_exception;
orig_user_exception_handler = EG(user_exception_handler);
if (call_user_function_ex(CG(function_table), NULL, orig_user_exception_handler, &retval2, 1, params, 1, NULL TSRMLS_CC) == SUCCESS) {
if (retval2 != NULL) {
zval_ptr_dtor(&retval2);
}
ZVAL_OBJ(&params[0], old_exception);
ZVAL_COPY_VALUE(&orig_user_exception_handler, &EG(user_exception_handler));
ZVAL_UNDEF(&retval2);
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));
//??? zval_ptr_dtor(&EG(exception));
EG(exception) = NULL;
}
zval_ptr_dtor(&old_exception);
//??? zval_ptr_dtor(&old_exception);
} else {
EG(exception) = old_exception;
zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
@ -1359,14 +1334,14 @@ ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_co
} else if (type==ZEND_REQUIRE) {
va_end(files);
EG(active_op_array) = orig_op_array;
EG(return_value_ptr_ptr) = orig_retval_ptr_ptr;
//??? EG(return_value_ptr_ptr) = orig_retval_ptr_ptr;
CG(interactive) = orig_interactive;
return FAILURE;
}
}
va_end(files);
EG(active_op_array) = orig_op_array;
EG(return_value_ptr_ptr) = orig_retval_ptr_ptr;
//??? EG(return_value_ptr_ptr) = orig_retval_ptr_ptr;
CG(interactive) = orig_interactive;
return SUCCESS;
@ -1382,7 +1357,7 @@ ZEND_API char *zend_make_compiled_string_description(const char *name TSRMLS_DC)
char *compiled_string_description;
if (zend_is_compiling(TSRMLS_C)) {
cur_filename = zend_get_compiled_filename(TSRMLS_C);
cur_filename = zend_get_compiled_filename(TSRMLS_C)->val;
cur_lineno = zend_get_compiled_lineno(TSRMLS_C);
} else if (zend_is_executing(TSRMLS_C)) {
cur_filename = zend_get_executed_filename(TSRMLS_C);

View file

@ -66,6 +66,7 @@
/* all HAVE_XXX test have to be after the include of zend_config above */
#include <stdio.h>
#include <assert.h>
#ifdef HAVE_UNIX_H
# include <unix.h>
@ -252,7 +253,6 @@ char *alloca ();
#include "zend_alloc.h"
#include "zend_types.h"
#include "zend_string.h"
#ifdef HAVE_LIMITS_H
# include <limits.h>
@ -284,11 +284,10 @@ typedef enum {
} ZEND_RESULT_CODE;
#include "zend_hash.h"
#include "zend_ts_hash.h"
#include "zend_llist.h"
#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval **return_value_ptr, zval *this_ptr, int return_value_used TSRMLS_DC
#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, return_value_ptr, this_ptr, return_value_used TSRMLS_CC
#define INTERNAL_FUNCTION_PARAMETERS zend_uint param_count, zval *return_value, zval *this_ptr, int return_value_used TSRMLS_DC
#define INTERNAL_FUNCTION_PARAM_PASSTHRU param_count, return_value, this_ptr, return_value_used TSRMLS_CC
#if defined(__GNUC__) && __GNUC__ >= 3 && !defined(__INTEL_COMPILER) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX) && !defined(__osf__)
void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((noreturn));
@ -296,75 +295,23 @@ void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((nore
# define zend_error_noreturn zend_error
#endif
/*
* zval
*/
typedef struct _zend_class_entry zend_class_entry;
typedef struct _zend_guard {
zend_bool in_get;
zend_bool in_set;
zend_bool in_unset;
zend_bool in_isset;
zend_bool dummy; /* sizeof(zend_guard) must not be equal to sizeof(void*) */
} zend_guard;
typedef struct _zend_object {
zend_class_entry *ce;
HashTable *properties;
zval **properties_table;
HashTable *guards; /* protects from __get/__set ... recursion */
} zend_object;
#include "zend_object_handlers.h"
#include "zend_ast.h"
typedef union _zvalue_value {
long lval; /* long value */
double dval; /* double value */
struct {
char *val;
int len;
} str;
HashTable *ht; /* hash table value */
zend_object_value obj;
zend_ast *ast;
} zvalue_value;
/* overloaded elements data types */
#define OE_IS_ARRAY (1<<0)
#define OE_IS_OBJECT (1<<1)
#define OE_IS_METHOD (1<<2)
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount__gc;
zend_uchar type; /* active type */
zend_uchar is_ref__gc;
};
#define Z_REFCOUNT_PP(ppz) Z_REFCOUNT_P(*(ppz))
#define Z_SET_REFCOUNT_PP(ppz, rc) Z_SET_REFCOUNT_P(*(ppz), rc)
#define Z_ADDREF_PP(ppz) Z_ADDREF_P(*(ppz))
#define Z_DELREF_PP(ppz) Z_DELREF_P(*(ppz))
#define Z_ISREF_PP(ppz) Z_ISREF_P(*(ppz))
#define Z_SET_ISREF_PP(ppz) Z_SET_ISREF_P(*(ppz))
#define Z_UNSET_ISREF_PP(ppz) Z_UNSET_ISREF_P(*(ppz))
#define Z_SET_ISREF_TO_PP(ppz, isref) Z_SET_ISREF_TO_P(*(ppz), isref)
#define Z_REFCOUNT_P(pz) zval_refcount_p(pz)
#define Z_REFCOUNT_P(pz) zval_refcount_p(pz)
#define Z_SET_REFCOUNT_P(pz, rc) zval_set_refcount_p(pz, rc)
#define Z_ADDREF_P(pz) zval_addref_p(pz)
#define Z_DELREF_P(pz) zval_delref_p(pz)
#define Z_ISREF_P(pz) zval_isref_p(pz)
#define Z_SET_ISREF_P(pz) zval_set_isref_p(pz)
#define Z_UNSET_ISREF_P(pz) zval_unset_isref_p(pz)
#define Z_SET_ISREF_TO_P(pz, isref) zval_set_isref_to_p(pz, isref)
#define Z_ADDREF_P(pz) zval_addref_p(pz)
#define Z_DELREF_P(pz) zval_delref_p(pz)
#define Z_REFCOUNT(z) Z_REFCOUNT_P(&(z))
#define Z_REFCOUNT(z) Z_REFCOUNT_P(&(z))
#define Z_SET_REFCOUNT(z, rc) Z_SET_REFCOUNT_P(&(z), rc)
#define Z_ADDREF(z) Z_ADDREF_P(&(z))
#define Z_DELREF(z) Z_DELREF_P(&(z))
#define Z_ISREF(z) Z_ISREF_P(&(z))
#define Z_SET_ISREF(z) Z_SET_ISREF_P(&(z))
#define Z_UNSET_ISREF(z) Z_UNSET_ISREF_P(&(z))
#define Z_SET_ISREF_TO(z, isref) Z_SET_ISREF_TO_P(&(z), isref)
#define Z_ADDREF(z) Z_ADDREF_P(&(z))
#define Z_DELREF(z) Z_DELREF_P(&(z))
#if ZEND_DEBUG
#define zend_always_inline inline
@ -395,36 +342,26 @@ struct _zval_struct {
# define UNEXPECTED(condition) (condition)
#endif
#include "zend_string.h"
static zend_always_inline zend_uint zval_refcount_p(zval* pz) {
return pz->refcount__gc;
ZEND_ASSERT(Z_REFCOUNTED_P(pz));
return Z_COUNTED_P(pz)->refcount;
}
static zend_always_inline zend_uint zval_set_refcount_p(zval* pz, zend_uint rc) {
return pz->refcount__gc = rc;
ZEND_ASSERT(Z_REFCOUNTED_P(pz));
return Z_COUNTED_P(pz)->refcount = rc;
}
static zend_always_inline zend_uint zval_addref_p(zval* pz) {
return ++pz->refcount__gc;
ZEND_ASSERT(Z_REFCOUNTED_P(pz));
return ++Z_COUNTED_P(pz)->refcount;
}
static zend_always_inline zend_uint zval_delref_p(zval* pz) {
return --pz->refcount__gc;
}
static zend_always_inline zend_bool zval_isref_p(zval* pz) {
return pz->is_ref__gc;
}
static zend_always_inline zend_bool zval_set_isref_p(zval* pz) {
return pz->is_ref__gc = 1;
}
static zend_always_inline zend_bool zval_unset_isref_p(zval* pz) {
return pz->is_ref__gc = 0;
}
static zend_always_inline zend_bool zval_set_isref_to_p(zval* pz, zend_bool isref) {
return pz->is_ref__gc = isref;
ZEND_ASSERT(Z_REFCOUNTED_P(pz));
return --Z_COUNTED_P(pz)->refcount;
}
/* excpt.h on Digital Unix 4.0 defines function_table */
@ -442,20 +379,18 @@ typedef struct _zend_serialize_data zend_serialize_data;
typedef struct _zend_unserialize_data zend_unserialize_data;
struct _zend_trait_method_reference {
const char* method_name;
unsigned int mname_len;
zend_string *method_name;
zend_class_entry *ce;
const char* class_name;
unsigned int cname_len;
zend_string *class_name;
};
typedef struct _zend_trait_method_reference zend_trait_method_reference;
struct _zend_trait_precedence {
zend_trait_method_reference *trait_method;
zend_class_entry** exclude_from_classes;
zend_trait_method_reference *trait_method;
union {
zend_class_entry *ce;
zend_string *class_name;
} *exclude_from_classes;
};
typedef struct _zend_trait_precedence zend_trait_precedence;
@ -465,8 +400,7 @@ struct _zend_trait_alias {
/**
* name for method to be added
*/
const char* alias;
unsigned int alias_len;
zend_string *alias;
/**
* modifiers to be set on trait method
@ -477,17 +411,16 @@ typedef struct _zend_trait_alias zend_trait_alias;
struct _zend_class_entry {
char type;
const char *name;
zend_uint name_length;
zend_string *name;
struct _zend_class_entry *parent;
int refcount;
zend_uint ce_flags;
HashTable function_table;
HashTable properties_info;
zval **default_properties_table;
zval **default_static_members_table;
zval **static_members_table;
zval *default_properties_table;
zval *default_static_members_table;
zval *static_members_table;
HashTable constants_table;
int default_properties_count;
int default_static_members_count;
@ -508,14 +441,14 @@ struct _zend_class_entry {
zend_class_iterator_funcs iterator_funcs;
/* handlers */
zend_object_value (*create_object)(zend_class_entry *class_type TSRMLS_DC);
zend_object* (*create_object)(zend_class_entry *class_type TSRMLS_DC);
zend_object_iterator *(*get_iterator)(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
int (*interface_gets_implemented)(zend_class_entry *iface, zend_class_entry *class_type TSRMLS_DC); /* a class implements this interface */
union _zend_function *(*get_static_method)(zend_class_entry *ce, char* method, int method_len TSRMLS_DC);
union _zend_function *(*get_static_method)(zend_class_entry *ce, zend_string* method TSRMLS_DC);
/* serializer callbacks */
int (*serialize)(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC);
int (*unserialize)(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC);
int (*unserialize)(zval *object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC);
zend_class_entry **interfaces;
zend_uint num_interfaces;
@ -527,11 +460,10 @@ struct _zend_class_entry {
union {
struct {
const char *filename;
zend_string *filename;
zend_uint line_start;
zend_uint line_end;
const char *doc_comment;
zend_uint doc_comment_len;
zend_string *doc_comment;
} user;
struct {
const struct _zend_function_entry *builtin_functions;
@ -577,36 +509,6 @@ typedef int (*zend_write_func_t)(const char *str, uint str_length);
#define ZEND_TRUTH(x) ((x) ? 1 : 0)
#define ZEND_LOG_XOR(a, b) (ZEND_TRUTH(a) ^ ZEND_TRUTH(b))
/* data types */
/* All data types <= IS_BOOL have their constructor/destructors skipped */
#define IS_NULL 0
#define IS_LONG 1
#define IS_DOUBLE 2
#define IS_BOOL 3
#define IS_ARRAY 4
#define IS_OBJECT 5
#define IS_STRING 6
#define IS_RESOURCE 7
#define IS_CONSTANT 8
#define IS_CONSTANT_ARRAY 9
#define IS_CONSTANT_AST 10
#define IS_CALLABLE 11
/* Ugly hack to support constants as static array indices */
#define IS_CONSTANT_TYPE_MASK 0x00f
#define IS_CONSTANT_UNQUALIFIED 0x010
#define IS_CONSTANT_INDEX 0x080
#define IS_LEXICAL_VAR 0x020
#define IS_LEXICAL_REF 0x040
#define IS_CONSTANT_IN_NAMESPACE 0x100
#define IS_CONSTANT_TYPE(type) (((type) & IS_CONSTANT_TYPE_MASK) >= IS_CONSTANT && ((type) & IS_CONSTANT_TYPE_MASK) <= IS_CONSTANT_AST)
/* overloaded elements data types */
#define OE_IS_ARRAY (1<<0)
#define OE_IS_OBJECT (1<<1)
#define OE_IS_METHOD (1<<2)
int zend_startup(zend_utility_functions *utility_functions, char **extensions TSRMLS_DC);
void zend_shutdown(TSRMLS_D);
void zend_register_standard_ini_entries(TSRMLS_D);
@ -677,17 +579,8 @@ END_EXTERN_C()
/* FIXME: Check if we can save if (ptr) too */
#define STR_FREE(ptr) if (ptr) { str_efree(ptr); }
#define STR_FREE_REL(ptr) if (ptr) { str_efree_rel(ptr); }
#ifndef ZTS
#define STR_EMPTY_ALLOC() CG(interned_empty_string)? CG(interned_empty_string) : estrndup("", sizeof("")-1)
#else
#define STR_EMPTY_ALLOC() estrndup("", sizeof("")-1)
#endif
#define STR_REALLOC(ptr, size) \
ptr = (char *) erealloc(ptr, size);
//???#define STR_FREE(ptr) if (ptr) { str_efree(ptr); }
//???#define STR_FREE_REL(ptr) if (ptr) { str_efree_rel(ptr); }
/* output support */
#define ZEND_WRITE(str, str_len) zend_write((str), (str_len))
@ -749,28 +642,26 @@ END_EXTERN_C()
#define ZMSG_LOG_SCRIPT_NAME 6L
#define ZMSG_MEMORY_LEAKS_GRAND_TOTAL 7L
#define INIT_PZVAL(z) \
(z)->refcount__gc = 1; \
(z)->is_ref__gc = 0;
#define INIT_ZVAL(z) z = zval_used_for_init;
#define ALLOC_INIT_ZVAL(zp) \
ALLOC_ZVAL(zp); \
INIT_ZVAL(*zp);
#define MAKE_STD_ZVAL(zv) \
ALLOC_ZVAL(zv); \
INIT_PZVAL(zv);
#define PZVAL_IS_REF(z) Z_ISREF_P(z)
#define ZVAL_COPY_VALUE(z, v) \
do { \
(z)->value = (v)->value; \
Z_TYPE_P(z) = Z_TYPE_P(v); \
} while (0)
#define ZVAL_COPY(z, v) \
do { \
ZVAL_COPY_VALUE(z, v); \
if (Z_REFCOUNTED_P(z)) { \
Z_ADDREF_P(z); \
} \
} while (0)
#define ZVAL_DUP(z, v) \
do { \
ZVAL_COPY_VALUE(z, v); \
zval_copy_ctor(z); \
} while (0)
#define INIT_PZVAL_COPY(z, v) \
do { \
ZVAL_COPY_VALUE(z, v); \
@ -778,43 +669,39 @@ END_EXTERN_C()
Z_UNSET_ISREF_P(z); \
} while (0)
#define SEPARATE_ZVAL(ppzv) \
do { \
if (Z_REFCOUNT_PP((ppzv)) > 1) { \
zval *new_zv; \
Z_DELREF_PP(ppzv); \
ALLOC_ZVAL(new_zv); \
INIT_PZVAL_COPY(new_zv, *(ppzv)); \
*(ppzv) = new_zv; \
zval_copy_ctor(new_zv); \
// TODO: support objects and resources???
#define SEPARATE_ZVAL(zv) do { \
if (Z_REFCOUNTED_P(zv)) { \
if (Z_REFCOUNT_P(zv) > 1) { \
Z_DELREF_P(zv); \
zval_copy_ctor(zv); \
Z_SET_REFCOUNT_P(zv, 1); \
} \
} \
} while (0)
#define SEPARATE_ZVAL_IF_NOT_REF(ppzv) \
if (!PZVAL_IS_REF(*ppzv)) { \
SEPARATE_ZVAL(ppzv); \
#define SEPARATE_ZVAL_IF_NOT_REF(zv) \
if (!Z_ISREF_P(zv)) { \
SEPARATE_ZVAL(zv); \
}
#define SEPARATE_ZVAL_TO_MAKE_IS_REF(ppzv) \
if (!PZVAL_IS_REF(*ppzv)) { \
SEPARATE_ZVAL(ppzv); \
Z_SET_ISREF_PP((ppzv)); \
#define SEPARATE_ZVAL_TO_MAKE_IS_REF(zv) \
if (!Z_ISREF_P(zv)) { \
zval ref; \
ZVAL_COPY_VALUE(&ref, zv); \
SEPARATE_ZVAL(&ref); \
ZVAL_NEW_REF(zv, &ref); \
}
#define COPY_PZVAL_TO_ZVAL(zv, pzv) \
(zv) = *(pzv); \
ZVAL_COPY_VALUE(&(zv), (pzv)); \
if (Z_REFCOUNT_P(pzv)>1) { \
zval_copy_ctor(&(zv)); \
Z_DELREF_P((pzv)); \
} else { \
FREE_ZVAL(pzv); \
} \
INIT_PZVAL(&(zv));
#define MAKE_COPY_ZVAL(ppzv, pzv) \
INIT_PZVAL_COPY(pzv, *(ppzv)); \
zval_copy_ctor((pzv));
//??? INIT_PZVAL(&(zv));
#define REPLACE_ZVAL_VALUE(ppzv_dest, pzv_src, copy) { \
int is_ref, refcount; \
\
@ -831,11 +718,8 @@ END_EXTERN_C()
}
#define SEPARATE_ARG_IF_REF(varptr) \
if (PZVAL_IS_REF(varptr)) { \
zval *original_var = varptr; \
ALLOC_ZVAL(varptr); \
INIT_PZVAL_COPY(varptr, original_var); \
zval_copy_ctor(varptr); \
if (Z_ISREF_P(varptr)) { \
ZVAL_DUP(varptr, Z_REFVAL_P(varptr)); \
} else { \
Z_ADDREF_P(varptr); \
}
@ -860,7 +744,7 @@ typedef enum {
typedef struct {
zend_error_handling_t handling;
zend_class_entry *exception;
zval *user_handler;
zval user_handler;
} zend_error_handling;
ZEND_API void zend_save_error_handling(zend_error_handling *current TSRMLS_DC);

File diff suppressed because it is too large Load diff

View file

@ -43,11 +43,11 @@ typedef struct _zend_function_entry {
typedef struct _zend_fcall_info {
size_t size;
HashTable *function_table;
zval *function_name;
zval function_name;
HashTable *symbol_table;
zval **retval_ptr_ptr;
zval *retval;
zend_uint param_count;
zval ***params;
zval *params;
zval *object_ptr;
zend_bool no_separation;
} zend_fcall_info;
@ -170,13 +170,9 @@ typedef struct _zend_fcall_info_cache {
#define INIT_OVERLOADED_CLASS_ENTRY_EX(class_container, class_name, class_name_len, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) \
{ \
const char *cl_name = class_name; \
int _len = class_name_len; \
class_container.name = zend_new_interned_string(cl_name, _len+1, 0 TSRMLS_CC); \
if (class_container.name == cl_name) { \
class_container.name = zend_strndup(cl_name, _len); \
} \
class_container.name_length = _len; \
zend_string *cl_name; \
cl_name = STR_INIT(class_name, class_name_len, 1); \
class_container.name = zend_new_interned_string(cl_name TSRMLS_CC); \
INIT_CLASS_ENTRY_INIT_METHODS(class_container, functions, handle_fcall, handle_propget, handle_propset, handle_propunset, handle_propisset) \
}
@ -236,9 +232,9 @@ int zend_next_free_module(void);
BEGIN_EXTERN_C()
ZEND_API int zend_get_parameters(int ht, int param_count, ...);
ZEND_API int _zend_get_parameters_array(int ht, int param_count, zval **argument_array TSRMLS_DC);
ZEND_API int _zend_get_parameters_array(int ht, int param_count, zval *argument_array TSRMLS_DC);
ZEND_API ZEND_ATTRIBUTE_DEPRECATED int zend_get_parameters_ex(int param_count, ...);
ZEND_API int _zend_get_parameters_array_ex(int param_count, zval ***argument_array TSRMLS_DC);
ZEND_API int _zend_get_parameters_array_ex(int param_count, zval *argument_array TSRMLS_DC);
/* internal function to efficiently copy parameters when executing __call() */
ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array TSRMLS_DC);
@ -260,7 +256,7 @@ ZEND_API char *zend_zval_type_name(const zval *arg);
ZEND_API int zend_parse_method_parameters(int num_args TSRMLS_DC, zval *this_ptr, const char *type_spec, ...);
ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args TSRMLS_DC, zval *this_ptr, const char *type_spec, ...);
ZEND_API int zend_parse_parameter(int flags, int arg_num TSRMLS_DC, zval **arg, const char *spec, ...);
ZEND_API int zend_parse_parameter(int flags, int arg_num TSRMLS_DC, zval *arg, const char *spec, ...);
/* End of parameter parsing API -- andrei */
@ -276,7 +272,7 @@ ZEND_API void zend_destroy_modules(void);
ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce, const zend_function *fptr, int error_type TSRMLS_DC);
ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *class_entry TSRMLS_DC);
ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce, char *parent_name TSRMLS_DC);
ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce TSRMLS_DC);
ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *orig_class_entry TSRMLS_DC);
ZEND_API void zend_class_implements(zend_class_entry *class_entry TSRMLS_DC, int num_interfaces, ...);
@ -304,8 +300,8 @@ ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, char **cal
ZEND_API zend_bool zend_make_callable(zval *callable, char **callable_name TSRMLS_DC);
ZEND_API const char *zend_get_module_version(const char *module_name);
ZEND_API int zend_get_module_started(const char *module_name);
ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment TSRMLS_DC);
ZEND_API int zend_declare_property(zend_class_entry *ce, const char *name, int name_length, zval *property, int access_type TSRMLS_DC);
ZEND_API int zend_declare_property_ex(zend_class_entry *ce, const char *name, int name_length, zval *property, int access_type, const char *doc_comment, int doc_comment_len TSRMLS_DC);
ZEND_API int zend_declare_property_null(zend_class_entry *ce, const char *name, int name_length, int access_type TSRMLS_DC);
ZEND_API int zend_declare_property_bool(zend_class_entry *ce, const char *name, int name_length, long value, int access_type TSRMLS_DC);
ZEND_API int zend_declare_property_long(zend_class_entry *ce, const char *name, int name_length, long value, int access_type TSRMLS_DC);
@ -343,15 +339,15 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const c
ZEND_API zval *zend_read_static_property(zend_class_entry *scope, const char *name, int name_length, zend_bool silent TSRMLS_DC);
ZEND_API zend_class_entry *zend_get_class_entry(const zval *zobject TSRMLS_DC);
ZEND_API int zend_get_object_classname(const zval *object, const char **class_name, zend_uint *class_name_len TSRMLS_DC);
ZEND_API zend_string *zend_get_object_classname(const zval *object TSRMLS_DC);
ZEND_API char *zend_get_type_by_const(int type);
#define getThis() (this_ptr)
#define WRONG_PARAM_COUNT ZEND_WRONG_PARAM_COUNT()
#define WRONG_PARAM_COUNT_WITH_RETVAL(ret) ZEND_WRONG_PARAM_COUNT_WITH_RETVAL(ret)
#define ARG_COUNT(dummy) (ht)
#define ZEND_NUM_ARGS() (ht)
#define ARG_COUNT(dummy) (param_count)
#define ZEND_NUM_ARGS() (param_count)
#define ZEND_WRONG_PARAM_COUNT() { zend_wrong_param_count(TSRMLS_C); return; }
#define ZEND_WRONG_PARAM_COUNT_WITH_RETVAL(ret) { zend_wrong_param_count(TSRMLS_C); return ret; }
@ -378,23 +374,25 @@ ZEND_API int add_assoc_function(zval *arg, const char *key, void (*function_ptr)
ZEND_API int add_assoc_long_ex(zval *arg, const char *key, uint key_len, long n);
ZEND_API int add_assoc_null_ex(zval *arg, const char *key, uint key_len);
ZEND_API int add_assoc_bool_ex(zval *arg, const char *key, uint key_len, int b);
ZEND_API int add_assoc_resource_ex(zval *arg, const char *key, uint key_len, int r);
ZEND_API int add_assoc_resource_ex(zval *arg, const char *key, uint key_len, zend_resource *r);
ZEND_API int add_assoc_double_ex(zval *arg, const char *key, uint key_len, double d);
ZEND_API int add_assoc_str_ex(zval *arg, const char *key, uint key_len, zend_string *str);
ZEND_API int add_assoc_string_ex(zval *arg, const char *key, uint key_len, char *str, int duplicate);
ZEND_API int add_assoc_stringl_ex(zval *arg, const char *key, uint key_len, char *str, uint length, int duplicate);
ZEND_API int add_assoc_zval_ex(zval *arg, const char *key, uint key_len, zval *value);
#define add_assoc_long(__arg, __key, __n) add_assoc_long_ex(__arg, __key, strlen(__key)+1, __n)
#define add_assoc_null(__arg, __key) add_assoc_null_ex(__arg, __key, strlen(__key) + 1)
#define add_assoc_bool(__arg, __key, __b) add_assoc_bool_ex(__arg, __key, strlen(__key)+1, __b)
#define add_assoc_resource(__arg, __key, __r) add_assoc_resource_ex(__arg, __key, strlen(__key)+1, __r)
#define add_assoc_double(__arg, __key, __d) add_assoc_double_ex(__arg, __key, strlen(__key)+1, __d)
#define add_assoc_string(__arg, __key, __str, __duplicate) add_assoc_string_ex(__arg, __key, strlen(__key)+1, __str, __duplicate)
#define add_assoc_stringl(__arg, __key, __str, __length, __duplicate) add_assoc_stringl_ex(__arg, __key, strlen(__key)+1, __str, __length, __duplicate)
#define add_assoc_zval(__arg, __key, __value) add_assoc_zval_ex(__arg, __key, strlen(__key)+1, __value)
#define add_assoc_long(__arg, __key, __n) add_assoc_long_ex(__arg, __key, strlen(__key), __n)
#define add_assoc_null(__arg, __key) add_assoc_null_ex(__arg, __key, strlen(__key))
#define add_assoc_bool(__arg, __key, __b) add_assoc_bool_ex(__arg, __key, strlen(__key), __b)
#define add_assoc_resource(__arg, __key, __r) add_assoc_resource_ex(__arg, __key, strlen(__key), __r)
#define add_assoc_double(__arg, __key, __d) add_assoc_double_ex(__arg, __key, strlen(__key), __d)
#define add_assoc_str(__arg, __key, __str) add_assoc_str_ex(__arg, __key, strlen(__key), __str)
#define add_assoc_string(__arg, __key, __str, __duplicate) add_assoc_string_ex(__arg, __key, strlen(__key), __str, __duplicate)
#define add_assoc_stringl(__arg, __key, __str, __length, __duplicate) add_assoc_stringl_ex(__arg, __key, strlen(__key), __str, __length, __duplicate)
#define add_assoc_zval(__arg, __key, __value) add_assoc_zval_ex(__arg, __key, strlen(__key), __value)
/* unset() functions are only suported for legacy modules and null() functions should be used */
#define add_assoc_unset(__arg, __key) add_assoc_null_ex(__arg, __key, strlen(__key) + 1)
#define add_assoc_unset(__arg, __key) add_assoc_null_ex(__arg, __key, strlen(__key))
#define add_index_unset(__arg, __key) add_index_null(__arg, __key)
#define add_next_index_unset(__arg) add_next_index_null(__arg)
#define add_property_unset(__arg, __key) add_property_null(__arg, __key)
@ -402,8 +400,9 @@ ZEND_API int add_assoc_zval_ex(zval *arg, const char *key, uint key_len, zval *v
ZEND_API int add_index_long(zval *arg, ulong idx, long n);
ZEND_API int add_index_null(zval *arg, ulong idx);
ZEND_API int add_index_bool(zval *arg, ulong idx, int b);
ZEND_API int add_index_resource(zval *arg, ulong idx, int r);
ZEND_API int add_index_resource(zval *arg, ulong idx, zend_resource *r);
ZEND_API int add_index_double(zval *arg, ulong idx, double d);
ZEND_API int add_index_str(zval *arg, ulong idx, zend_string *str);
ZEND_API int add_index_string(zval *arg, ulong idx, const char *str, int duplicate);
ZEND_API int add_index_stringl(zval *arg, ulong idx, const char *str, uint length, int duplicate);
ZEND_API int add_index_zval(zval *arg, ulong index, zval *value);
@ -411,46 +410,48 @@ ZEND_API int add_index_zval(zval *arg, ulong index, zval *value);
ZEND_API int add_next_index_long(zval *arg, long n);
ZEND_API int add_next_index_null(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_resource(zval *arg, zend_resource *r);
ZEND_API int add_next_index_double(zval *arg, double d);
ZEND_API int add_next_index_str(zval *arg, zend_string *str);
ZEND_API int add_next_index_string(zval *arg, const char *str, int duplicate);
ZEND_API int add_next_index_stringl(zval *arg, const char *str, uint length, int duplicate);
ZEND_API int add_next_index_zval(zval *arg, zval *value);
ZEND_API int add_get_assoc_string_ex(zval *arg, const char *key, uint key_len, const char *str, void **dest, int duplicate);
ZEND_API int add_get_assoc_stringl_ex(zval *arg, const char *key, uint key_len, const char *str, uint length, void **dest, int duplicate);
ZEND_API zval *add_get_assoc_string_ex(zval *arg, const char *key, uint key_len, const char *str, int duplicate);
ZEND_API zval *add_get_assoc_stringl_ex(zval *arg, const char *key, uint key_len, const char *str, uint length, int duplicate);
#define add_get_assoc_string(__arg, __key, __str, __dest, __duplicate) add_get_assoc_string_ex(__arg, __key, strlen(__key)+1, __str, __dest, __duplicate)
#define add_get_assoc_stringl(__arg, __key, __str, __length, __dest, __duplicate) add_get_assoc_stringl_ex(__arg, __key, strlen(__key)+1, __str, __length, __dest, __duplicate)
#define add_get_assoc_string(__arg, __key, __str, __duplicate) add_get_assoc_string_ex(__arg, __key, strlen(__key), __str, __duplicate)
#define add_get_assoc_stringl(__arg, __key, __str, __length, __duplicate) add_get_assoc_stringl_ex(__arg, __key, strlen(__key), __str, __length, __duplicate)
ZEND_API int add_get_index_long(zval *arg, ulong idx, long l, void **dest);
ZEND_API int add_get_index_double(zval *arg, ulong idx, double d, void **dest);
ZEND_API int add_get_index_string(zval *arg, ulong idx, const char *str, void **dest, int duplicate);
ZEND_API int add_get_index_stringl(zval *arg, ulong idx, const char *str, uint length, void **dest, int duplicate);
ZEND_API zval *add_get_index_long(zval *arg, ulong idx, long l);
ZEND_API zval *add_get_index_double(zval *arg, ulong idx, double d);
ZEND_API zval *add_get_index_str(zval *arg, ulong index, zend_string *str);
ZEND_API zval *add_get_index_string(zval *arg, ulong idx, const char *str, int duplicate);
ZEND_API zval *add_get_index_stringl(zval *arg, ulong idx, const char *str, uint length, int duplicate);
ZEND_API int array_set_zval_key(HashTable *ht, zval *key, zval *value);
ZEND_API int add_property_long_ex(zval *arg, const char *key, uint key_len, long l TSRMLS_DC);
ZEND_API int add_property_null_ex(zval *arg, const char *key, uint key_len TSRMLS_DC);
ZEND_API int add_property_bool_ex(zval *arg, const char *key, uint key_len, int b TSRMLS_DC);
ZEND_API int add_property_resource_ex(zval *arg, const char *key, uint key_len, long r TSRMLS_DC);
ZEND_API int add_property_resource_ex(zval *arg, const char *key, uint key_len, zend_resource *r TSRMLS_DC);
ZEND_API int add_property_double_ex(zval *arg, const char *key, uint key_len, double d TSRMLS_DC);
ZEND_API int add_property_string_ex(zval *arg, const char *key, uint key_len, const char *str, int duplicate TSRMLS_DC);
ZEND_API int add_property_stringl_ex(zval *arg, const char *key, uint key_len, const char *str, uint length, int duplicate TSRMLS_DC);
ZEND_API int add_property_zval_ex(zval *arg, const char *key, uint key_len, zval *value TSRMLS_DC);
#define add_property_long(__arg, __key, __n) add_property_long_ex(__arg, __key, strlen(__key)+1, __n TSRMLS_CC)
#define add_property_null(__arg, __key) add_property_null_ex(__arg, __key, strlen(__key) + 1 TSRMLS_CC)
#define add_property_bool(__arg, __key, __b) add_property_bool_ex(__arg, __key, strlen(__key)+1, __b TSRMLS_CC)
#define add_property_resource(__arg, __key, __r) add_property_resource_ex(__arg, __key, strlen(__key)+1, __r TSRMLS_CC)
#define add_property_double(__arg, __key, __d) add_property_double_ex(__arg, __key, strlen(__key)+1, __d TSRMLS_CC)
#define add_property_string(__arg, __key, __str, __duplicate) add_property_string_ex(__arg, __key, strlen(__key)+1, __str, __duplicate TSRMLS_CC)
#define add_property_stringl(__arg, __key, __str, __length, __duplicate) add_property_stringl_ex(__arg, __key, strlen(__key)+1, __str, __length, __duplicate TSRMLS_CC)
#define add_property_zval(__arg, __key, __value) add_property_zval_ex(__arg, __key, strlen(__key)+1, __value TSRMLS_CC)
#define add_property_long(__arg, __key, __n) add_property_long_ex(__arg, __key, strlen(__key), __n TSRMLS_CC)
#define add_property_null(__arg, __key) add_property_null_ex(__arg, __key, strlen(__key) TSRMLS_CC)
#define add_property_bool(__arg, __key, __b) add_property_bool_ex(__arg, __key, strlen(__key), __b TSRMLS_CC)
#define add_property_resource(__arg, __key, __r) add_property_resource_ex(__arg, __key, strlen(__key), __r TSRMLS_CC)
#define add_property_double(__arg, __key, __d) add_property_double_ex(__arg, __key, strlen(__key), __d TSRMLS_CC)
#define add_property_string(__arg, __key, __str, __duplicate) add_property_string_ex(__arg, __key, strlen(__key), __str, __duplicate TSRMLS_CC)
#define add_property_stringl(__arg, __key, __str, __length, __duplicate) add_property_stringl_ex(__arg, __key, strlen(__key), __str, __length, __duplicate TSRMLS_CC)
#define add_property_zval(__arg, __key, __value) add_property_zval_ex(__arg, __key, strlen(__key), __value TSRMLS_CC)
ZEND_API int call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, zend_uint param_count, zval *params[] TSRMLS_DC);
ZEND_API int call_user_function_ex(HashTable *function_table, zval **object_pp, zval *function_name, zval **retval_ptr_ptr, zend_uint param_count, zval **params[], int no_separation, HashTable *symbol_table TSRMLS_DC);
ZEND_API int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, zend_uint param_count, zval params[] TSRMLS_DC);
ZEND_API int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, zend_uint param_count, zval params[], int no_separation, HashTable *symbol_table TSRMLS_DC);
ZEND_API extern const zend_fcall_info empty_fcall_info;
ZEND_API extern const zend_fcall_info_cache empty_fcall_info_cache;
@ -475,11 +476,11 @@ ZEND_API void zend_fcall_info_args_clear(zend_fcall_info *fci, int free_mem);
/** Save current arguments from zend_fcall_info *fci
* params array will be set to NULL
*/
ZEND_API void zend_fcall_info_args_save(zend_fcall_info *fci, int *param_count, zval ****params);
ZEND_API void zend_fcall_info_args_save(zend_fcall_info *fci, int *param_count, zval **params);
/** Free arguments connected with zend_fcall_info *fci andset back saved ones.
*/
ZEND_API void zend_fcall_info_args_restore(zend_fcall_info *fci, int param_count, zval ***params);
ZEND_API void zend_fcall_info_args_restore(zend_fcall_info *fci, int param_count, zval *params);
/** Set or clear the arguments in the zend_call_info struct taking care of
* refcount. If args is NULL and arguments are set then those are cleared.
@ -490,7 +491,7 @@ ZEND_API int zend_fcall_info_args(zend_fcall_info *fci, zval *args TSRMLS_DC);
* If argc is 0 the arguments which are set will be cleared, else pass
* a variable amount of zval** arguments.
*/
ZEND_API int zend_fcall_info_argp(zend_fcall_info *fci TSRMLS_DC, int argc, zval ***argv);
ZEND_API int zend_fcall_info_argp(zend_fcall_info *fci TSRMLS_DC, int argc, zval *argv);
/** Set arguments in the zend_fcall_info struct taking care of refcount.
* If argc is 0 the arguments which are set will be cleared, else pass
@ -507,24 +508,22 @@ ZEND_API int zend_fcall_info_argn(zend_fcall_info *fci TSRMLS_DC, int argc, ...)
/** Call a function using information created by zend_fcall_info_init()/args().
* If args is given then those replace the argument info in fci is temporarily.
*/
ZEND_API int zend_fcall_info_call(zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval **retval, zval *args TSRMLS_DC);
ZEND_API int zend_fcall_info_call(zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval *retval, zval *args TSRMLS_DC);
ZEND_API int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TSRMLS_DC);
ZEND_API int zend_set_hash_symbol(zval *symbol, const char *name, int name_length, zend_bool is_ref, int num_symbol_tables, ...);
ZEND_API void zend_delete_variable(zend_execute_data *ex, HashTable *ht, const char *name, int name_len, ulong hash_value TSRMLS_DC);
ZEND_API void zend_delete_variable(zend_execute_data *ex, HashTable *ht, zend_string *name TSRMLS_DC);
ZEND_API int zend_delete_global_variable(const char *name, int name_len TSRMLS_DC);
ZEND_API int zend_delete_global_variable_ex(const char *name, int name_len, ulong hash_value TSRMLS_DC);
ZEND_API int zend_delete_global_variable(zend_string *name TSRMLS_DC);
ZEND_API void zend_reset_all_cv(HashTable *symbol_table TSRMLS_DC);
ZEND_API void zend_rebuild_symbol_table(TSRMLS_D);
ZEND_API const char* zend_find_alias_name(zend_class_entry *ce, const char *name, zend_uint len);
ZEND_API const char* zend_resolve_method_name(zend_class_entry *ce, zend_function *f);
ZEND_API zend_string *zend_find_alias_name(zend_class_entry *ce, zend_string *name);
ZEND_API zend_string *zend_resolve_method_name(zend_class_entry *ce, zend_function *f);
#define add_method(arg, key, method) add_assoc_function((arg), (key), (method))
@ -545,55 +544,38 @@ END_EXTERN_C()
#define CHECK_ZVAL_NULL_PATH(p) (Z_STRLEN_P(p) != strlen(Z_STRVAL_P(p)))
#define CHECK_NULL_PATH(p, l) (strlen(p) != l)
#define ZVAL_RESOURCE(z, l) do { \
zval *__z = (z); \
Z_LVAL_P(__z) = l; \
Z_TYPE_P(__z) = IS_RESOURCE;\
} while (0)
#define ZVAL_BOOL(z, b) do { \
zval *__z = (z); \
Z_LVAL_P(__z) = ((b) != 0); \
Z_TYPE_P(__z) = IS_BOOL; \
} while (0)
#define ZVAL_NULL(z) { \
Z_TYPE_P(z) = IS_NULL; \
}
#define ZVAL_LONG(z, l) { \
zval *__z = (z); \
Z_LVAL_P(__z) = l; \
Z_TYPE_P(__z) = IS_LONG; \
}
#define ZVAL_DOUBLE(z, d) { \
zval *__z = (z); \
Z_DVAL_P(__z) = d; \
Z_TYPE_P(__z) = IS_DOUBLE; \
}
#define ZVAL_STRING(z, s, duplicate) do { \
const char *__s=(s); \
zval *__z = (z); \
Z_STRLEN_P(__z) = strlen(__s); \
Z_STRVAL_P(__z) = (duplicate?estrndup(__s, Z_STRLEN_P(__z)):(char*)__s);\
Z_TYPE_P(__z) = IS_STRING; \
} while (0)
#define ZVAL_STRINGL(z, s, l, duplicate) do { \
const char *__s=(s); int __l=l; \
#define ZVAL_STRINGL(z, s, l) do { \
zval *__z = (z); \
Z_STRLEN_P(__z) = __l; \
Z_STRVAL_P(__z) = (duplicate?estrndup(__s, __l):(char*)__s);\
Z_TYPE_P(__z) = IS_STRING; \
int __l = l; \
ZVAL_STR(__z, STR_ALLOC(__l, 0)); \
memcpy(Z_STRVAL_P(__z), (s), __l + 1); \
} while (0)
#define ZVAL_EMPTY_STRING(z) do { \
zval *__z = (z); \
Z_STRLEN_P(__z) = 0; \
Z_STRVAL_P(__z) = STR_EMPTY_ALLOC();\
Z_TYPE_P(__z) = IS_STRING; \
#define ZVAL_STRING(z, s) do { \
const char *_s = (s); \
int _l = strlen(_s); \
ZVAL_STRINGL(z, _s, _l); \
} while (0)
#define ZVAL_EMPTY_STRING(z) do { \
ZVAL_STRINGL(z, "", 0); \
} while (0)
#define ZVAL_PSTRINGL(z, s, l) do { \
zval *__z = (z); \
int __l = l; \
ZVAL_STR(__z, STR_ALLOC(__l, 1)); \
memcpy(Z_STRVAL_P(__z), (s), __l + 1); \
} while (0)
#define ZVAL_PSTRING(z, s) do { \
const char *_s = (s); \
int _l = strlen(_s); \
ZVAL_PSTRINGL(z, _s, _l); \
} while (0)
#define ZVAL_EMPTY_PSTRING(z) do { \
ZVAL_PSTRINGL(z, "", 0); \
} while (0)
#define ZVAL_ZVAL(z, zv, copy, dtor) do { \
@ -607,32 +589,32 @@ END_EXTERN_C()
if (!copy) { \
ZVAL_NULL(__zv); \
} \
zval_ptr_dtor(&__zv); \
zval_ptr_dtor(__zv); \
} \
} while (0)
#define ZVAL_FALSE(z) ZVAL_BOOL(z, 0)
#define ZVAL_TRUE(z) ZVAL_BOOL(z, 1)
#define RETVAL_RESOURCE(l) ZVAL_RESOURCE(return_value, l)
#define RETVAL_BOOL(b) ZVAL_BOOL(return_value, b)
#define RETVAL_NULL() ZVAL_NULL(return_value)
#define RETVAL_LONG(l) ZVAL_LONG(return_value, l)
#define RETVAL_DOUBLE(d) ZVAL_DOUBLE(return_value, d)
#define RETVAL_STRING(s, duplicate) ZVAL_STRING(return_value, s, duplicate)
#define RETVAL_STRINGL(s, l, duplicate) ZVAL_STRINGL(return_value, s, l, duplicate)
#define RETVAL_STR(s) ZVAL_STR(return_value, s)
#define RETVAL_STRING(s) ZVAL_STRING(return_value, s)
#define RETVAL_STRINGL(s, l) ZVAL_STRINGL(return_value, s, l)
#define RETVAL_EMPTY_STRING() ZVAL_EMPTY_STRING(return_value)
#define RETVAL_ZVAL(zv, copy, dtor) ZVAL_ZVAL(return_value, zv, copy, dtor)
#define RETVAL_FALSE ZVAL_BOOL(return_value, 0)
#define RETVAL_TRUE ZVAL_BOOL(return_value, 1)
#define RETURN_RESOURCE(l) { RETVAL_RESOURCE(l); return; }
#define RETURN_BOOL(b) { RETVAL_BOOL(b); return; }
#define RETURN_NULL() { RETVAL_NULL(); return;}
#define RETURN_LONG(l) { RETVAL_LONG(l); return; }
#define RETURN_DOUBLE(d) { RETVAL_DOUBLE(d); return; }
#define RETURN_STRING(s, duplicate) { RETVAL_STRING(s, duplicate); return; }
#define RETURN_STRINGL(s, l, duplicate) { RETVAL_STRINGL(s, l, duplicate); return; }
#define RETURN_STR(s) { RETVAL_STR(s); return; }
#define RETURN_STRING(s) { RETVAL_STRING(s); return; }
#define RETURN_STRINGL(s, l) { RETVAL_STRINGL(s, l); return; }
#define RETURN_EMPTY_STRING() { RETVAL_EMPTY_STRING(); return; }
#define RETURN_ZVAL(zv, copy, dtor) { RETVAL_ZVAL(zv, copy, dtor); return; }
#define RETURN_FALSE { RETVAL_FALSE; return; }
@ -643,11 +625,11 @@ END_EXTERN_C()
if (Z_ISREF_P(_z)) { \
RETVAL_ZVAL(_z, 1, 0); \
} else { \
zval_ptr_dtor(&return_value); \
Z_ADDREF_P(_z); \
*return_value_ptr = _z; \
zval_ptr_dtor(return_value); \
ZVAL_COPY(return_value, _z); \
} \
} while (0)
#define RETURN_ZVAL_FAST(z) { RETVAL_ZVAL_FAST(z); return; }
#define SET_VAR_STRING(n, v) { \
@ -699,7 +681,7 @@ END_EXTERN_C()
zval **orig_var; \
\
if (zend_hash_find(symtable, (name), (name_length), (void **) &orig_var)==SUCCESS \
&& PZVAL_IS_REF(*orig_var)) { \
&& Z_ISREF_PP(orig_var)) { \
Z_SET_REFCOUNT_P(var, Z_REFCOUNT_PP(orig_var)); \
Z_SET_ISREF_P(var); \
\

View file

@ -1758,10 +1758,11 @@ static void zend_mm_safe_error(zend_mm_heap *heap,
uint error_lineno;
TSRMLS_FETCH();
if (zend_is_compiling(TSRMLS_C)) {
error_filename = zend_get_compiled_filename(TSRMLS_C);
zend_string *str = zend_get_compiled_filename(TSRMLS_C);
error_filename = str ? str->val : NULL;
error_lineno = zend_get_compiled_lineno(TSRMLS_C);
} else if (EG(in_execution)) {
error_filename = EG(active_op_array)?EG(active_op_array)->filename:NULL;
error_filename = EG(active_op_array)?EG(active_op_array)->filename->val:NULL;
error_lineno = EG(opline_ptr)?(*EG(opline_ptr))->lineno:0;
} else {
error_filename = NULL;

View file

@ -162,17 +162,10 @@ ZEND_API size_t zend_memory_peak_usage(int real_usage TSRMLS_DC);
END_EXTERN_C()
/* fast cache for zval's */
#define ALLOC_ZVAL(z) \
(z) = (zval *) emalloc(sizeof(zval))
#define FREE_ZVAL(z) \
efree_rel(z)
#define ALLOC_ZVAL_REL(z) \
(z) = (zval *) emalloc_rel(sizeof(zval))
#define FREE_ZVAL_REL(z) \
efree_rel(z)
//???#define ALLOC_ZVAL(z) (z) = (zval *) emalloc(sizeof(zval))
//???#define FREE_ZVAL(z) efree_rel(z)
//???#define ALLOC_ZVAL_REL(z) (z) = (zval *) emalloc_rel(sizeof(zval))
//???#define FREE_ZVAL_REL(z) efree_rel(z)
/* fast cache for HashTables */
#define ALLOC_HASHTABLE(ht) \

View file

@ -28,8 +28,7 @@ ZEND_API zend_ast *zend_ast_create_constant(zval *zv)
zend_ast *ast = emalloc(sizeof(zend_ast) + sizeof(zval));
ast->kind = ZEND_CONST;
ast->children = 0;
ast->u.val = (zval*)(ast + 1);
INIT_PZVAL_COPY(ast->u.val, zv);
ZVAL_COPY_VALUE(&ast->u.val, zv);
return ast;
}
@ -68,7 +67,7 @@ ZEND_API int zend_ast_is_ct_constant(zend_ast *ast)
int i;
if (ast->kind == ZEND_CONST) {
return !IS_CONSTANT_TYPE(Z_TYPE_P(ast->u.val));
return !IS_CONSTANT_TYPE(Z_TYPE(ast->u.val));
} else {
for (i = 0; i < ast->children; i++) {
if ((&ast->u.child)[i]) {
@ -223,10 +222,9 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s
zval_dtor(&op2);
break;
case ZEND_CONST:
*result = *ast->u.val;
zval_copy_ctor(result);
ZVAL_DUP(result, &ast->u.val);
if (IS_CONSTANT_TYPE(Z_TYPE_P(result))) {
zval_update_constant_ex(&result, (void *) 1, scope TSRMLS_CC);
zval_update_constant_ex(result, (void *) 1, scope TSRMLS_CC);
}
break;
case ZEND_BOOL_AND:
@ -287,8 +285,8 @@ ZEND_API zend_ast *zend_ast_copy(zend_ast *ast)
if (ast == NULL) {
return NULL;
} else if (ast->kind == ZEND_CONST) {
zend_ast *copy = zend_ast_create_constant(ast->u.val);
zval_copy_ctor(copy->u.val);
zend_ast *copy = zend_ast_create_constant(&ast->u.val);
zval_copy_ctor(&copy->u.val);
return copy;
} else {
switch (ast->children) {
@ -317,7 +315,7 @@ ZEND_API void zend_ast_destroy(zend_ast *ast)
int i;
if (ast->kind == ZEND_CONST) {
zval_dtor(ast->u.val);
zval_dtor(&ast->u.val);
} else {
for (i = 0; i < ast->children; i++) {
if ((&ast->u.child)[i]) {

View file

@ -40,7 +40,7 @@ struct _zend_ast {
unsigned short kind;
unsigned short children;
union {
zval *val;
zval val;
zend_ast *child;
} u;
};

File diff suppressed because it is too large Load diff

View file

@ -37,7 +37,7 @@
typedef struct _zend_closure {
zend_object std;
zend_function func;
zval *this_ptr;
zval this_ptr;
HashTable *debug_info;
} zend_closure;
@ -48,24 +48,20 @@ static zend_object_handlers closure_handlers;
ZEND_METHOD(Closure, __invoke) /* {{{ */
{
zend_function *func = EG(current_execute_data)->function_state.function;
zval ***arguments;
zval *closure_result_ptr = NULL;
zval *arguments;
arguments = emalloc(sizeof(zval**) * ZEND_NUM_ARGS());
arguments = emalloc(sizeof(zval) * ZEND_NUM_ARGS());
if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), arguments) == FAILURE) {
efree(arguments);
zend_error(E_RECOVERABLE_ERROR, "Cannot get arguments for calling closure");
RETVAL_FALSE;
} else if (call_user_function_ex(CG(function_table), NULL, this_ptr, &closure_result_ptr, ZEND_NUM_ARGS(), arguments, 1, NULL TSRMLS_CC) == FAILURE) {
} else if (call_user_function_ex(CG(function_table), NULL, this_ptr, return_value, ZEND_NUM_ARGS(), arguments, 1, NULL TSRMLS_CC) == FAILURE) {
RETVAL_FALSE;
} else if (closure_result_ptr) {
zval_ptr_dtor(&return_value);
*return_value_ptr = closure_result_ptr;
}
efree(arguments);
/* destruct the function also, then - we have allocated it in get_method */
efree((char*)func->internal_function.function_name);
STR_RELEASE(func->internal_function.function_name);
efree(func);
}
/* }}} */
@ -76,13 +72,13 @@ ZEND_METHOD(Closure, bind)
{
zval *newthis, *zclosure, *scope_arg = NULL;
zend_closure *closure;
zend_class_entry *ce, **ce_p;
zend_class_entry *ce;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oo!|z", &zclosure, zend_ce_closure, &newthis, &scope_arg) == FAILURE) {
RETURN_NULL();
}
closure = (zend_closure *)zend_object_store_get_object(zclosure TSRMLS_CC);
closure = (zend_closure *)Z_OBJ_P(zclosure);
if ((newthis != NULL) && (closure->func.common.fn_flags & ZEND_ACC_STATIC)) {
zend_error(E_WARNING, "Cannot bind an instance to a static closure");
@ -94,32 +90,25 @@ ZEND_METHOD(Closure, bind)
} else if (Z_TYPE_P(scope_arg) == IS_NULL) {
ce = NULL;
} else {
char *class_name;
int class_name_len;
zend_string *class_name;
zval tmp_zval;
INIT_ZVAL(tmp_zval);
if (Z_TYPE_P(scope_arg) == IS_STRING) {
class_name = Z_STRVAL_P(scope_arg);
class_name_len = Z_STRLEN_P(scope_arg);
class_name = Z_STR_P(scope_arg);
} else {
tmp_zval = *scope_arg;
zval_copy_ctor(&tmp_zval);
ZVAL_DUP(&tmp_zval, scope_arg);
convert_to_string(&tmp_zval);
class_name = Z_STRVAL(tmp_zval);
class_name_len = Z_STRLEN(tmp_zval);
class_name = Z_STR(tmp_zval);
}
if ((class_name_len == sizeof("static") - 1) &&
(memcmp("static", class_name, sizeof("static") - 1) == 0)) {
if ((class_name->len == sizeof("static") - 1) &&
(memcmp("static", class_name->val, sizeof("static") - 1) == 0)) {
ce = closure->func.common.scope;
}
else if (zend_lookup_class_ex(class_name, class_name_len, NULL, 1, &ce_p TSRMLS_CC) == FAILURE) {
zend_error(E_WARNING, "Class '%s' not found", class_name);
else if ((ce = zend_lookup_class_ex(class_name, NULL, 1 TSRMLS_CC)) == NULL) {
zend_error(E_WARNING, "Class '%s' not found", class_name->val);
zval_dtor(&tmp_zval);
RETURN_NULL();
} else {
ce = *ce_p;
}
zval_dtor(&tmp_zval);
}
@ -140,13 +129,13 @@ static zend_function *zend_closure_get_constructor(zval *object TSRMLS_DC) /* {{
static int zend_closure_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
{
return (Z_OBJ_HANDLE_P(o1) != Z_OBJ_HANDLE_P(o2));
return (Z_OBJ_P(o1) != Z_OBJ_P(o2));
}
/* }}} */
ZEND_API zend_function *zend_get_closure_invoke_method(zval *obj TSRMLS_DC) /* {{{ */
{
zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
zend_closure *closure = (zend_closure *)Z_OBJ_P(obj);
zend_function *invoke = (zend_function*)emalloc(sizeof(zend_function));
invoke->common = closure->func.common;
@ -155,47 +144,45 @@ ZEND_API zend_function *zend_get_closure_invoke_method(zval *obj TSRMLS_DC) /* {
invoke->internal_function.handler = ZEND_MN(Closure___invoke);
invoke->internal_function.module = 0;
invoke->internal_function.scope = zend_ce_closure;
invoke->internal_function.function_name = estrndup(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1);
invoke->internal_function.function_name = STR_INIT(ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1, 0);
return invoke;
}
/* }}} */
ZEND_API const zend_function *zend_get_closure_method_def(zval *obj TSRMLS_DC) /* {{{ */
{
zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
zend_closure *closure = (zend_closure *)Z_OBJ_P(obj);
return &closure->func;
}
/* }}} */
ZEND_API zval* zend_get_closure_this_ptr(zval *obj TSRMLS_DC) /* {{{ */
{
zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
return closure->this_ptr;
zend_closure *closure = (zend_closure *)Z_OBJ_P(obj);
return &closure->this_ptr;
}
/* }}} */
static zend_function *zend_closure_get_method(zval **object_ptr, char *method_name, int method_len, const zend_literal *key TSRMLS_DC) /* {{{ */
static zend_function *zend_closure_get_method(zval *object_ptr, zend_string *method, const zend_literal *key TSRMLS_DC) /* {{{ */
{
char *lc_name;
ALLOCA_FLAG(use_heap)
zend_string *lc_name;
lc_name = do_alloca(method_len + 1, use_heap);
zend_str_tolower_copy(lc_name, method_name, method_len);
if ((method_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) &&
lc_name = STR_ALLOC(method->len, 0);
zend_str_tolower_copy(lc_name->val, method->val, method->len);
if ((method->len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) &&
memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
) {
free_alloca(lc_name, use_heap);
return zend_get_closure_invoke_method(*object_ptr TSRMLS_CC);
STR_FREE(lc_name);
return zend_get_closure_invoke_method(object_ptr TSRMLS_CC);
}
free_alloca(lc_name, use_heap);
return std_object_handlers.get_method(object_ptr, method_name, method_len, key TSRMLS_CC);
STR_FREE(lc_name);
return std_object_handlers.get_method(object_ptr, method, key TSRMLS_CC);
}
/* }}} */
static zval *zend_closure_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
{
ZEND_CLOSURE_PROPERTY_ERROR();
Z_ADDREF(EG(uninitialized_zval));
return &EG(uninitialized_zval);
}
/* }}} */
@ -206,7 +193,7 @@ static void zend_closure_write_property(zval *object, zval *member, zval *value,
}
/* }}} */
static zval **zend_closure_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
static zval *zend_closure_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
{
ZEND_CLOSURE_PROPERTY_ERROR();
return NULL;
@ -228,7 +215,7 @@ static void zend_closure_unset_property(zval *object, zval *member, const zend_l
}
/* }}} */
static void zend_closure_free_storage(void *object TSRMLS_DC) /* {{{ */
static void zend_closure_free_storage(zend_object *object TSRMLS_DC) /* {{{ */
{
zend_closure *closure = (zend_closure *)object;
@ -250,7 +237,7 @@ static void zend_closure_free_storage(void *object TSRMLS_DC) /* {{{ */
efree(closure->debug_info);
}
if (closure->this_ptr) {
if (Z_TYPE(closure->this_ptr) != IS_UNDEF) {
zval_ptr_dtor(&closure->this_ptr);
}
@ -258,34 +245,31 @@ static void zend_closure_free_storage(void *object TSRMLS_DC) /* {{{ */
}
/* }}} */
static zend_object_value zend_closure_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
static zend_object *zend_closure_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
{
zend_closure *closure;
zend_object_value object;
closure = emalloc(sizeof(zend_closure));
memset(closure, 0, sizeof(zend_closure));
zend_object_std_init(&closure->std, class_type TSRMLS_CC);
closure->std.handlers = &closure_handlers;
object.handle = zend_objects_store_put(closure, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) zend_closure_free_storage, NULL TSRMLS_CC);
object.handlers = &closure_handlers;
return object;
return (zend_object*)closure;
}
/* }}} */
static zend_object_value zend_closure_clone(zval *zobject TSRMLS_DC) /* {{{ */
static zend_object *zend_closure_clone(zval *zobject TSRMLS_DC) /* {{{ */
{
zend_closure *closure = (zend_closure *)zend_object_store_get_object(zobject TSRMLS_CC);
zend_closure *closure = (zend_closure *)Z_OBJ_P(zobject);
zval result;
zend_create_closure(&result, &closure->func, closure->func.common.scope, closure->this_ptr TSRMLS_CC);
return Z_OBJVAL(result);
zend_create_closure(&result, &closure->func, closure->func.common.scope, &closure->this_ptr TSRMLS_CC);
return Z_OBJ(result);
}
/* }}} */
int zend_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zval **zobj_ptr TSRMLS_DC) /* {{{ */
int zend_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zval *zobj_ptr TSRMLS_DC) /* {{{ */
{
zend_closure *closure;
@ -293,17 +277,17 @@ int zend_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function
return FAILURE;
}
closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
closure = (zend_closure *)Z_OBJ_P(obj);
*fptr_ptr = &closure->func;
if (closure->this_ptr) {
if (Z_TYPE(closure->this_ptr) != IS_UNDEF) {
if (zobj_ptr) {
*zobj_ptr = closure->this_ptr;
ZVAL_COPY_VALUE(zobj_ptr, &closure->this_ptr);
}
*ce_ptr = Z_OBJCE_P(closure->this_ptr);
*ce_ptr = Z_OBJCE(closure->this_ptr);
} else {
if (zobj_ptr) {
*zobj_ptr = NULL;
ZVAL_UNDEF(zobj_ptr);
}
*ce_ptr = closure->func.common.scope;
}
@ -313,8 +297,8 @@ int zend_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function
static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
{
zend_closure *closure = (zend_closure *)zend_object_store_get_object(object TSRMLS_CC);
zval *val;
zend_closure *closure = (zend_closure *)Z_OBJ_P(object);
zval val;
struct _zend_arg_info *arg_info = closure->func.common.arg_info;
*is_temp = 0;
@ -326,22 +310,20 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_
if (closure->debug_info->nApplyCount == 0) {
if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) {
HashTable *static_variables = closure->func.op_array.static_variables;
MAKE_STD_ZVAL(val);
array_init(val);
zend_hash_copy(Z_ARRVAL_P(val), static_variables, (copy_ctor_func_t)zval_add_ref, NULL, sizeof(zval*));
zend_hash_update(closure->debug_info, "static", sizeof("static"), (void *) &val, sizeof(zval *), NULL);
array_init(&val);
zend_hash_copy(Z_ARRVAL(val), static_variables, zval_add_ref);
zend_hash_str_update(closure->debug_info, "static", sizeof("static")-1, &val);
}
if (closure->this_ptr) {
Z_ADDREF_P(closure->this_ptr);
zend_symtable_update(closure->debug_info, "this", sizeof("this"), (void *) &closure->this_ptr, sizeof(zval *), NULL);
if (Z_TYPE(closure->this_ptr) != IS_UNDEF) {
Z_ADDREF(closure->this_ptr);
zend_hash_str_update(closure->debug_info, "this", sizeof("this")-1, &closure->this_ptr);
}
if (arg_info) {
zend_uint i, required = closure->func.common.required_num_args;
MAKE_STD_ZVAL(val);
array_init(val);
array_init(&val);
for (i = 0; i < closure->func.common.num_args; i++) {
char *name, *info;
@ -356,12 +338,12 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_
i + 1);
}
info_len = zend_spprintf(&info, 0, "%s",
i >= required ? "<optional>" : "<required>");
add_assoc_stringl_ex(val, name, name_len + 1, info, info_len, 0);
i >= required ? "<optional>" : "<required>");
add_assoc_stringl_ex(&val, name, name_len, info, info_len, 0);
efree(name);
arg_info++;
}
zend_hash_update(closure->debug_info, "parameter", sizeof("parameter"), (void *) &val, sizeof(zval *), NULL);
zend_hash_str_update(closure->debug_info, "parameter", sizeof("parameter")-1, &val);
}
}
@ -369,12 +351,12 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_
}
/* }}} */
static HashTable *zend_closure_get_gc(zval *obj, zval ***table, int *n TSRMLS_DC) /* {{{ */
static HashTable *zend_closure_get_gc(zval *obj, zval **table, int *n TSRMLS_DC) /* {{{ */
{
zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
zend_closure *closure = (zend_closure *)Z_OBJ_P(obj);
*table = closure->this_ptr ? &closure->this_ptr : NULL;
*n = closure->this_ptr ? 1 : 0;
*table = Z_TYPE(closure->this_ptr) != IS_NULL ? &closure->this_ptr : NULL;
*n = Z_TYPE(closure->this_ptr) != IS_NULL ? 1 : 0;
return (closure->func.type == ZEND_USER_FUNCTION) ?
closure->func.op_array.static_variables : NULL;
}
@ -418,6 +400,8 @@ void zend_register_closure_ce(TSRMLS_D) /* {{{ */
zend_ce_closure->unserialize = zend_class_unserialize_deny;
memcpy(&closure_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
closure_handlers.free_obj = zend_closure_free_storage;
closure_handlers.clone_obj = NULL;
closure_handlers.get_constructor = zend_closure_get_constructor;
closure_handlers.get_method = zend_closure_get_method;
closure_handlers.write_property = zend_closure_write_property;
@ -439,7 +423,7 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
object_init_ex(res, zend_ce_closure);
closure = (zend_closure *)zend_object_store_get_object(res TSRMLS_CC);
closure = (zend_closure *)Z_OBJ_P(res);
closure->func = *func;
closure->func.common.prototype = NULL;
@ -464,12 +448,12 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
/* verify that we aren't binding internal function to a wrong scope */
if(func->common.scope != NULL) {
if(scope && !instanceof_function(scope, func->common.scope TSRMLS_CC)) {
zend_error(E_WARNING, "Cannot bind function %s::%s to scope class %s", func->common.scope->name, func->common.function_name, scope->name);
zend_error(E_WARNING, "Cannot bind function %s::%s to scope class %s", func->common.scope->name->val, func->common.function_name->val, scope->name->val);
scope = NULL;
}
if(scope && this_ptr && (func->common.fn_flags & ZEND_ACC_STATIC) == 0 &&
!instanceof_function(Z_OBJCE_P(this_ptr), closure->func.common.scope TSRMLS_CC)) {
zend_error(E_WARNING, "Cannot bind function %s::%s to object of class %s", func->common.scope->name, func->common.function_name, Z_OBJCE_P(this_ptr)->name);
zend_error(E_WARNING, "Cannot bind function %s::%s to object of class %s", func->common.scope->name->val, func->common.function_name->val, Z_OBJCE_P(this_ptr)->name->val);
scope = NULL;
this_ptr = NULL;
}
@ -487,14 +471,13 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
if (scope) {
closure->func.common.fn_flags |= ZEND_ACC_PUBLIC;
if (this_ptr && (closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0) {
closure->this_ptr = this_ptr;
Z_ADDREF_P(this_ptr);
ZVAL_COPY(&closure->this_ptr, this_ptr);
} else {
closure->func.common.fn_flags |= ZEND_ACC_STATIC;
closure->this_ptr = NULL;
ZVAL_UNDEF(&closure->this_ptr);
}
} else {
closure->this_ptr = NULL;
ZVAL_UNDEF(&closure->this_ptr);
}
}
/* }}} */

File diff suppressed because it is too large Load diff

View file

@ -45,10 +45,9 @@
#define RESET_DOC_COMMENT() \
{ \
if (CG(doc_comment)) { \
efree(CG(doc_comment)); \
STR_RELEASE(CG(doc_comment)); \
CG(doc_comment) = NULL; \
} \
CG(doc_comment_len) = 0; \
}
typedef struct _zend_op_array zend_op_array;
@ -68,13 +67,9 @@ typedef struct _zend_compiler_context {
typedef struct _zend_literal {
zval constant;
zend_ulong hash_value;
zend_uint cache_slot;
} zend_literal;
#define Z_HASH_P(zv) \
(((zend_literal*)(zv))->hash_value)
typedef union _znode_op {
zend_uint constant;
zend_uint var;
@ -222,12 +217,10 @@ char *zend_visibility_string(zend_uint fn_flags);
typedef struct _zend_property_info {
zend_uint flags;
const char *name;
int name_length;
zend_string *name;
ulong h;
int offset;
const char *doc_comment;
int doc_comment_len;
zend_string *doc_comment;
zend_class_entry *ce;
} zend_property_info;
@ -237,6 +230,8 @@ typedef struct _zend_arg_info {
zend_uint name_len;
const char *class_name;
zend_uint class_name_len;
//??? zend_string *name;
//??? zend_string *class_name;
zend_uchar type_hint;
zend_uchar pass_by_reference;
zend_bool allow_null;
@ -258,19 +253,13 @@ typedef struct _zend_internal_function_info {
zend_bool _is_variadic;
} zend_internal_function_info;
typedef struct _zend_compiled_variable {
const char *name;
int name_len;
ulong hash_value;
} zend_compiled_variable;
struct _zend_op_array {
/* Common elements */
zend_uchar type;
const char *function_name;
zend_string *function_name;
zend_class_entry *scope;
zend_uint fn_flags;
union _zend_function *prototype;
zend_function *prototype;
zend_uint num_args;
zend_uint required_num_args;
zend_arg_info *arg_info;
@ -281,7 +270,7 @@ struct _zend_op_array {
zend_op *opcodes;
zend_uint last;
zend_compiled_variable *vars;
zend_string **vars;
int last_var;
zend_uint T;
@ -301,11 +290,10 @@ struct _zend_op_array {
zend_uint this_var;
const char *filename;
zend_string *filename;
zend_uint line_start;
zend_uint line_end;
const char *doc_comment;
zend_uint doc_comment_len;
zend_string *doc_comment;
zend_uint early_binding; /* the linked list of delayed declarations */
zend_literal *literals;
@ -324,10 +312,10 @@ struct _zend_op_array {
typedef struct _zend_internal_function {
/* Common elements */
zend_uchar type;
const char * function_name;
zend_string* function_name;
zend_class_entry *scope;
zend_uint fn_flags;
union _zend_function *prototype;
zend_function *prototype;
zend_uint num_args;
zend_uint required_num_args;
zend_arg_info *arg_info;
@ -337,14 +325,14 @@ typedef struct _zend_internal_function {
struct _zend_module_entry *module;
} zend_internal_function;
#define ZEND_FN_SCOPE_NAME(function) ((function) && (function)->common.scope ? (function)->common.scope->name : "")
#define ZEND_FN_SCOPE_NAME(function) ((function) && (function)->common.scope ? (function)->common.scope->name->val : "")
typedef union _zend_function {
union _zend_function {
zend_uchar type; /* MUST be the first element of this struct! */
struct {
zend_uchar type; /* never used */
const char *function_name;
zend_string *function_name;
zend_class_entry *scope;
zend_uint fn_flags;
union _zend_function *prototype;
@ -355,12 +343,12 @@ typedef union _zend_function {
zend_op_array op_array;
zend_internal_function internal_function;
} zend_function;
};
typedef struct _zend_function_state {
zend_function *function;
void **arguments;
zval *arguments;
} zend_function_state;
@ -377,12 +365,10 @@ typedef struct _list_llist_element {
znode value;
} list_llist_element;
union _temp_variable;
typedef struct _call_slot {
zend_function *fbc;
zval *object;
zend_class_entry *called_scope;
zval object;
zend_uint num_additional_args;
zend_bool is_ctor_call;
zend_bool is_ctor_result_used;
@ -392,28 +378,28 @@ struct _zend_execute_data {
struct _zend_op *opline;
zend_function_state function_state;
zend_op_array *op_array;
zval *object;
zval object;
HashTable *symbol_table;
struct _zend_execute_data *prev_execute_data;
zval *old_error_reporting;
zval old_error_reporting;
zend_bool nested;
zval **original_return_value;
zend_class_entry *current_scope;
zend_class_entry *current_called_scope;
zval *current_this;
//??? zval **original_return_value;
//??? zend_class_entry *current_scope;
//??? zend_class_entry *current_called_scope;
//??? zval *current_this;
struct _zend_op *fast_ret; /* used by FAST_CALL/FAST_RET (finally keyword) */
zval *delayed_exception;
zend_object *delayed_exception;
call_slot *call_slots;
call_slot *call;
};
#define EX(element) execute_data.element
#define EX_TMP_VAR(ex, n) ((temp_variable*)(((char*)(ex)) + ((int)(n))))
#define EX_TMP_VAR_NUM(ex, n) (EX_TMP_VAR(ex, 0) - (1 + (n)))
#define EX_CV_NUM(ex, n) (((zval***)(((char*)(ex))+ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data))))+(n))
#define EX_VAR_2(ex, n) ((zval*)(((char*)(ex)) + ((int)(n))))
#define EX_VAR_NUM_2(ex, n) (EX_VAR_2(ex, 0) - (1 + (n)))
#define EX_VAR(n) EX_VAR_2(execute_data, n)
#define EX_VAR_NUM(n) EX_VAR_NUM_2(execute_data, n)
#define IS_CONST (1<<0)
#define IS_TMP_VAR (1<<1)
@ -439,9 +425,9 @@ ZEND_API int lex_scan(zval *zendlval TSRMLS_DC);
void startup_scanner(TSRMLS_D);
void shutdown_scanner(TSRMLS_D);
ZEND_API char *zend_set_compiled_filename(const char *new_compiled_filename TSRMLS_DC);
ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename TSRMLS_DC);
ZEND_API char *zend_get_compiled_filename(TSRMLS_D);
ZEND_API zend_string *zend_set_compiled_filename(zend_string *new_compiled_filename TSRMLS_DC);
ZEND_API void zend_restore_compiled_filename(zend_string *original_compiled_filename TSRMLS_DC);
ZEND_API zend_string *zend_get_compiled_filename(TSRMLS_D);
ZEND_API int zend_get_compiled_lineno(TSRMLS_D);
ZEND_API size_t zend_get_scanned_file_offset(TSRMLS_D);
@ -449,7 +435,7 @@ void zend_resolve_non_class_name(znode *element_name, zend_bool *check_namespace
void zend_resolve_function_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC);
void zend_resolve_const_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC);
void zend_resolve_class_name(znode *class_name TSRMLS_DC);
ZEND_API const char* zend_get_compiled_variable_name(const zend_op_array *op_array, zend_uint var, int* name_len);
ZEND_API zend_string *zend_get_compiled_variable_name(const zend_op_array *op_array, zend_uint var);
#ifdef ZTS
const char *zend_get_zendtext(TSRMLS_D);
@ -573,7 +559,7 @@ void zend_do_default_before_statement(const znode *case_list, znode *default_tok
void zend_do_begin_class_declaration(const znode *class_token, znode *class_name, const znode *parent_class_name TSRMLS_DC);
void zend_do_end_class_declaration(const znode *class_token, const znode *parent_token TSRMLS_DC);
void zend_do_declare_property(const znode *var_name, const znode *value, zend_uint access_type TSRMLS_DC);
void zend_do_declare_property(znode *var_name, const znode *value, zend_uint access_type TSRMLS_DC);
void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_DC);
void zend_do_fetch_property(znode *result, znode *object, const znode *property TSRMLS_DC);
@ -670,7 +656,7 @@ ZEND_API void function_add_ref(zend_function *function);
ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSRMLS_DC);
ZEND_API zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC);
ZEND_API zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC);
ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval **retval, int file_count, ...);
ZEND_API int zend_execute_scripts(int type TSRMLS_DC, zval *retval, int file_count, ...);
ZEND_API int open_file_for_scanning(zend_file_handle *file_handle TSRMLS_DC);
ZEND_API void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_size TSRMLS_DC);
ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC);
@ -692,8 +678,8 @@ ZEND_API void zend_mangle_property_name(char **dest, int *dest_length, const cha
zend_unmangle_property_name_ex(mangled_property, mangled_property_len, class_name, prop_name, NULL)
ZEND_API int zend_unmangle_property_name_ex(const char *mangled_property, int mangled_property_len, const char **class_name, const char **prop_name, int *prop_len);
#define ZEND_FUNCTION_DTOR (void (*)(void *)) zend_function_dtor
#define ZEND_CLASS_DTOR (void (*)(void *)) destroy_zend_class
#define ZEND_FUNCTION_DTOR (void (*)(zval *)) zend_function_dtor
#define ZEND_CLASS_DTOR (void (*)(zval *)) destroy_zend_class
zend_op *get_next_op(zend_op_array *op_array TSRMLS_DC);
void init_op(zend_op *op TSRMLS_DC);
@ -710,19 +696,19 @@ ZEND_API char *zend_make_compiled_string_description(const char *name TSRMLS_DC)
ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers TSRMLS_DC);
int zend_get_class_fetch_type(const char *class_name, uint class_name_len);
typedef zend_bool (*zend_auto_global_callback)(const char *name, uint name_len TSRMLS_DC);
typedef zend_bool (*zend_auto_global_callback)(zend_string *name TSRMLS_DC);
typedef struct _zend_auto_global {
const char *name;
uint name_len;
//??? const char *name;
//??? uint name_len;
zend_string *name;
zend_auto_global_callback auto_global_callback;
zend_bool jit;
zend_bool armed;
} zend_auto_global;
ZEND_API int zend_register_auto_global(const char *name, uint name_len, zend_bool jit, zend_auto_global_callback auto_global_callback TSRMLS_DC);
ZEND_API int zend_register_auto_global(zend_string *name, zend_bool jit, zend_auto_global_callback auto_global_callback TSRMLS_DC);
ZEND_API void zend_activate_auto_globals(TSRMLS_D);
ZEND_API zend_bool zend_is_auto_global(const char *name, uint name_len TSRMLS_DC);
ZEND_API zend_bool zend_is_auto_global_quick(const char *name, uint name_len, ulong hashval TSRMLS_DC);
ZEND_API zend_bool zend_is_auto_global(zend_string *name TSRMLS_DC);
ZEND_API size_t zend_dirname(char *path, size_t len);
int zendlex(znode *zendlval TSRMLS_DC);

View file

@ -32,13 +32,17 @@ void free_zend_constant(zend_constant *c)
if (!(c->flags & CONST_PERSISTENT)) {
zval_dtor(&c->value);
}
str_free(c->name);
STR_RELEASE(c->name);
}
void copy_zend_constant(zend_constant *c)
static void copy_zend_constant(zval *zv)
{
c->name = str_strndup(c->name, c->name_len - 1);
zend_constant *c = Z_PTR_P(zv);
Z_PTR_P(zv) = pemalloc(sizeof(zend_constant), c->flags & CONST_PERSISTENT);
memcpy(Z_PTR_P(zv), c, sizeof(zend_constant));
c->name = STR_DUP(c->name, c->flags & CONST_PERSISTENT);
if (!(c->flags & CONST_PERSISTENT)) {
zval_copy_ctor(&c->value);
}
@ -47,9 +51,7 @@ void copy_zend_constant(zend_constant *c)
void zend_copy_constants(HashTable *target, HashTable *source)
{
zend_constant tmp_constant;
zend_hash_copy(target, source, (copy_ctor_func_t) copy_zend_constant, &tmp_constant, sizeof(zend_constant));
zend_hash_copy(target, source, copy_zend_constant);
}
@ -149,8 +151,8 @@ ZEND_API void zend_register_null_constant(const char *name, uint name_len, int f
ZVAL_NULL(&c.value);
c.flags = flags;
c.name = zend_strndup(name, name_len-1);
c.name_len = name_len;
// TODO: remove -1 ???
c.name = STR_INIT(name, name_len-1, flags & CONST_PERSISTENT);
c.module_number = module_number;
zend_register_constant(&c TSRMLS_CC);
}
@ -161,8 +163,8 @@ ZEND_API void zend_register_bool_constant(const char *name, uint name_len, zend_
ZVAL_BOOL(&c.value, bval);
c.flags = flags;
c.name = zend_strndup(name, name_len-1);
c.name_len = name_len;
// TODO: remove -1 ???
c.name = STR_INIT(name, name_len-1, flags & CONST_PERSISTENT);
c.module_number = module_number;
zend_register_constant(&c TSRMLS_CC);
}
@ -173,8 +175,8 @@ ZEND_API void zend_register_long_constant(const char *name, uint name_len, long
ZVAL_LONG(&c.value, lval);
c.flags = flags;
c.name = zend_strndup(name, name_len-1);
c.name_len = name_len;
// TODO: remove -1 ???
c.name = STR_INIT(name, name_len-1, flags & CONST_PERSISTENT);
c.module_number = module_number;
zend_register_constant(&c TSRMLS_CC);
}
@ -186,8 +188,8 @@ ZEND_API void zend_register_double_constant(const char *name, uint name_len, dou
ZVAL_DOUBLE(&c.value, dval);
c.flags = flags;
c.name = zend_strndup(name, name_len-1);
c.name_len = name_len;
// TODO: remove -1 ???
c.name = STR_INIT(name, name_len-1, flags & CONST_PERSISTENT);
c.module_number = module_number;
zend_register_constant(&c TSRMLS_CC);
}
@ -197,10 +199,11 @@ ZEND_API void zend_register_stringl_constant(const char *name, uint name_len, ch
{
zend_constant c;
ZVAL_STRINGL(&c.value, strval, strlen, 0);
//??? ZVAL_STRINGL(&c.value, strval, strlen, 0);
ZVAL_STRINGL(&c.value, strval, strlen);
c.flags = flags;
c.name = zend_strndup(name, name_len-1);
c.name_len = name_len;
// TODO: remove -1 ???
c.name = STR_INIT(name, name_len-1, flags & CONST_PERSISTENT);
c.module_number = module_number;
zend_register_constant(&c TSRMLS_CC);
}
@ -211,45 +214,43 @@ ZEND_API void zend_register_string_constant(const char *name, uint name_len, cha
zend_register_stringl_constant(name, name_len, strval, strlen(strval), flags, module_number TSRMLS_CC);
}
static int zend_get_special_constant(const char *name, uint name_len, zend_constant **c TSRMLS_DC)
static zend_constant *zend_get_special_constant(const char *name, uint name_len TSRMLS_DC)
{
int ret;
zend_constant *c;
static char haltoff[] = "__COMPILER_HALT_OFFSET__";
if (!EG(in_execution)) {
return 0;
return NULL;
} else if (name_len == sizeof("__CLASS__")-1 &&
!memcmp(name, "__CLASS__", sizeof("__CLASS__")-1)) {
zend_constant tmp;
/* Returned constants may be cached, so they have to be stored */
if (EG(scope) && EG(scope)->name) {
int const_name_len;
char *const_name;
ALLOCA_FLAG(use_heap)
zend_string *const_name;
const_name_len = sizeof("\0__CLASS__") + EG(scope)->name_length;
const_name = do_alloca(const_name_len, use_heap);
memcpy(const_name, "\0__CLASS__", sizeof("\0__CLASS__")-1);
zend_str_tolower_copy(const_name + sizeof("\0__CLASS__")-1, EG(scope)->name, EG(scope)->name_length);
if (zend_hash_find(EG(zend_constants), const_name, const_name_len, (void**)c) == FAILURE) {
zend_hash_add(EG(zend_constants), const_name, const_name_len, (void*)&tmp, sizeof(zend_constant), (void**)c);
memset(*c, 0, sizeof(zend_constant));
Z_STRVAL((**c).value) = estrndup(EG(scope)->name, EG(scope)->name_length);
Z_STRLEN((**c).value) = EG(scope)->name_length;
Z_TYPE((**c).value) = IS_STRING;
const_name_len = sizeof("\0__CLASS__") + EG(scope)->name->len;
const_name = STR_ALLOC(const_name_len, 0);
memcpy(const_name->val, "\0__CLASS__", sizeof("\0__CLASS__")-1);
zend_str_tolower_copy(const_name->val + sizeof("\0__CLASS__")-1, EG(scope)->name->val, EG(scope)->name->len);
if ((c = zend_hash_find_ptr(EG(zend_constants), const_name)) == NULL) {
c = emalloc(sizeof(zend_constant));
memset(c, 0, sizeof(zend_constant));
ZVAL_STR(&c->value, STR_COPY(EG(scope)->name));
zend_hash_add_ptr(EG(zend_constants), const_name, c);
}
free_alloca(const_name, use_heap);
STR_RELEASE(const_name);
} else {
if (zend_hash_find(EG(zend_constants), "\0__CLASS__", sizeof("\0__CLASS__"), (void**)c) == FAILURE) {
zend_hash_add(EG(zend_constants), "\0__CLASS__", sizeof("\0__CLASS__"), (void*)&tmp, sizeof(zend_constant), (void**)c);
memset(*c, 0, sizeof(zend_constant));
Z_STRVAL((**c).value) = estrndup("", 0);
Z_STRLEN((**c).value) = 0;
Z_TYPE((**c).value) = IS_STRING;
zend_string *const_name = STR_INIT("\0__CLASS__", sizeof("\0__CLASS__")-1, 0);
if ((c = zend_hash_find_ptr(EG(zend_constants), const_name)) == NULL) {
c = emalloc(sizeof(zend_constant));
memset(c, 0, sizeof(zend_constant));
ZVAL_EMPTY_STRING(&c->value);
zend_hash_add_ptr(EG(zend_constants), const_name, c);
}
STR_RELEASE(const_name);
}
return 1;
return c;
} else if (name_len == sizeof("__COMPILER_HALT_OFFSET__")-1 &&
!memcmp(name, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1)) {
const char *cfilename;
@ -261,11 +262,11 @@ static int zend_get_special_constant(const char *name, uint name_len, zend_const
/* check for __COMPILER_HALT_OFFSET__ */
zend_mangle_property_name(&haltname, &len, haltoff,
sizeof("__COMPILER_HALT_OFFSET__") - 1, cfilename, clen, 0);
ret = zend_hash_find(EG(zend_constants), haltname, len+1, (void **) c);
c = zend_hash_str_find_ptr(EG(zend_constants), haltname, len);
efree(haltname);
return (ret == SUCCESS);
return c;
} else {
return 0;
return NULL;
}
}
@ -274,26 +275,21 @@ ZEND_API int zend_get_constant(const char *name, uint name_len, zval *result TSR
{
zend_constant *c;
int retval = 1;
char *lookup_name;
if (zend_hash_find(EG(zend_constants), name, name_len+1, (void **) &c) == FAILURE) {
lookup_name = zend_str_tolower_dup(name, name_len);
if (zend_hash_find(EG(zend_constants), lookup_name, name_len+1, (void **) &c)==SUCCESS) {
if ((c = zend_hash_str_find_ptr(EG(zend_constants), name, name_len)) == NULL) {
char *lcname = zend_str_tolower_dup(name, name_len);
if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, name_len)) != NULL) {
if (c->flags & CONST_CS) {
retval=0;
}
} else {
retval = zend_get_special_constant(name, name_len, &c TSRMLS_CC);
c = zend_get_special_constant(name, name_len TSRMLS_CC);
}
efree(lookup_name);
efree(lcname);
}
if (retval) {
*result = c->value;
zval_copy_ctor(result);
Z_SET_REFCOUNT_P(result, 1);
Z_UNSET_ISREF_P(result);
ZVAL_DUP(result, &c->value);
}
return retval;
@ -305,8 +301,8 @@ ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result,
int retval = 1;
const char *colon;
zend_class_entry *ce = NULL;
char *class_name;
zval **ret_constant;
zend_string *class_name;
zval *ret_constant;
/* Skip leading \\ */
if (name[0] == '\\') {
@ -319,11 +315,12 @@ ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result,
colon > name && (*(colon - 1) == ':')) {
int class_name_len = colon - name - 1;
int const_name_len = name_len - class_name_len - 2;
const char *constant_name = colon + 1;
char *lcname;
zend_string *constant_name = STR_INIT(colon + 1, const_name_len, 0);
zend_string *lcname;
class_name = estrndup(name, class_name_len);
lcname = zend_str_tolower_dup(class_name, class_name_len);
class_name = STR_INIT(name, class_name_len, 0);
lcname = STR_ALLOC(class_name_len, 0);
zend_str_tolower_copy(lcname->val, name, class_name_len);
if (!scope) {
if (EG(in_execution)) {
scope = EG(scope);
@ -333,16 +330,16 @@ ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result,
}
if (class_name_len == sizeof("self")-1 &&
!memcmp(lcname, "self", sizeof("self")-1)) {
!memcmp(lcname->val, "self", sizeof("self")-1)) {
if (scope) {
ce = scope;
} else {
zend_error(E_ERROR, "Cannot access self:: when no class scope is active");
retval = 0;
}
efree(lcname);
STR_FREE(lcname);
} else if (class_name_len == sizeof("parent")-1 &&
!memcmp(lcname, "parent", sizeof("parent")-1)) {
!memcmp(lcname->val, "parent", sizeof("parent")-1)) {
if (!scope) {
zend_error(E_ERROR, "Cannot access parent:: when no class scope is active");
} else if (!scope->parent) {
@ -350,30 +347,31 @@ ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result,
} else {
ce = scope->parent;
}
efree(lcname);
STR_FREE(lcname);
} else if (class_name_len == sizeof("static")-1 &&
!memcmp(lcname, "static", sizeof("static")-1)) {
!memcmp(lcname->val, "static", sizeof("static")-1)) {
if (EG(called_scope)) {
ce = EG(called_scope);
} else {
zend_error(E_ERROR, "Cannot access static:: when no class scope is active");
}
efree(lcname);
STR_FREE(lcname);
} else {
efree(lcname);
ce = zend_fetch_class(class_name, class_name_len, flags TSRMLS_CC);
STR_FREE(lcname);
ce = zend_fetch_class(class_name, flags TSRMLS_CC);
}
if (retval && ce) {
if (zend_hash_find(&ce->constants_table, constant_name, const_name_len+1, (void **) &ret_constant) != SUCCESS) {
if ((ret_constant = zend_hash_find(&ce->constants_table, constant_name)) == NULL) {
retval = 0;
if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) {
zend_error(E_ERROR, "Undefined class constant '%s::%s'", class_name, constant_name);
zend_error(E_ERROR, "Undefined class constant '%s::%s'", class_name->val, constant_name->val);
}
}
} else if (!ce) {
retval = 0;
}
efree(class_name);
STR_FREE(class_name);
STR_FREE(constant_name);
goto finish;
}
@ -383,35 +381,33 @@ ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result,
int prefix_len = colon - name;
int const_name_len = name_len - prefix_len - 1;
const char *constant_name = colon + 1;
char *lcname;
zend_string *lcname;
int found_const = 0;
lcname = zend_str_tolower_dup(name, prefix_len);
lcname = STR_ALLOC(prefix_len + 1 + const_name_len, 0);
zend_str_tolower_copy(lcname->val, name, prefix_len);
/* Check for namespace constant */
/* Concatenate lowercase namespace name and constant name */
lcname = erealloc(lcname, prefix_len + 1 + const_name_len + 1);
lcname[prefix_len] = '\\';
memcpy(lcname + prefix_len + 1, constant_name, const_name_len + 1);
lcname->val[prefix_len] = '\\';
memcpy(lcname->val + prefix_len + 1, constant_name, const_name_len + 1);
if (zend_hash_find(EG(zend_constants), lcname, prefix_len + 1 + const_name_len + 1, (void **) &c) == SUCCESS) {
if ((c = zend_hash_find_ptr(EG(zend_constants), lcname)) != NULL) {
found_const = 1;
} else {
/* try lowercase */
zend_str_tolower(lcname + prefix_len + 1, const_name_len);
if (zend_hash_find(EG(zend_constants), lcname, prefix_len + 1 + const_name_len + 1, (void **) &c) == SUCCESS) {
zend_str_tolower(lcname->val + prefix_len + 1, const_name_len);
lcname->h = 0; // reuse ???
if ((c = zend_hash_find_ptr(EG(zend_constants), lcname)) != NULL) {
if ((c->flags & CONST_CS) == 0) {
found_const = 1;
}
}
}
efree(lcname);
if(found_const) {
*result = c->value;
zval_update_constant_ex(&result, (void*)1, NULL TSRMLS_CC);
STR_FREE(lcname);
if (found_const) {
ZVAL_COPY_VALUE(result, &c->value);
zval_update_constant_ex(result, (void*)1, NULL TSRMLS_CC);
zval_copy_ctor(result);
Z_SET_REFCOUNT_P(result, 1);
Z_UNSET_ISREF_P(result);
return 1;
}
/* name requires runtime resolution, need to check non-namespaced name */
@ -424,9 +420,7 @@ ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result,
finish:
if (retval) {
zval_update_constant_ex(ret_constant, (void*)1, ce TSRMLS_CC);
*result = **ret_constant;
zval_copy_ctor(result);
INIT_PZVAL(result);
ZVAL_DUP(result, ret_constant);
}
return retval;
@ -439,28 +433,24 @@ zend_constant *zend_quick_get_constant(const zend_literal *key, ulong flags TSRM
{
zend_constant *c;
if (zend_hash_quick_find(EG(zend_constants), Z_STRVAL(key->constant), Z_STRLEN(key->constant) + 1, key->hash_value, (void **) &c) == FAILURE) {
if ((c = zend_hash_find_ptr(EG(zend_constants), Z_STR(key->constant))) == NULL) {
key++;
if (zend_hash_quick_find(EG(zend_constants), Z_STRVAL(key->constant), Z_STRLEN(key->constant) + 1, key->hash_value, (void **) &c) == FAILURE ||
if ((c = zend_hash_find_ptr(EG(zend_constants), Z_STR(key->constant))) == NULL ||
(c->flags & CONST_CS) != 0) {
if ((flags & (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) == (IS_CONSTANT_IN_NAMESPACE|IS_CONSTANT_UNQUALIFIED)) {
key++;
if (zend_hash_quick_find(EG(zend_constants), Z_STRVAL(key->constant), Z_STRLEN(key->constant) + 1, key->hash_value, (void **) &c) == FAILURE) {
if ((c = zend_hash_find_ptr(EG(zend_constants), Z_STR(key->constant))) == NULL) {
key++;
if (zend_hash_quick_find(EG(zend_constants), Z_STRVAL(key->constant), Z_STRLEN(key->constant) + 1, key->hash_value, (void **) &c) == FAILURE ||
if ((c = zend_hash_find_ptr(EG(zend_constants), Z_STR(key->constant))) == NULL ||
(c->flags & CONST_CS) != 0) {
key--;
if (!zend_get_special_constant(Z_STRVAL(key->constant), Z_STRLEN(key->constant), &c TSRMLS_CC)) {
return NULL;
}
c = zend_get_special_constant(Z_STRVAL(key->constant), Z_STRLEN(key->constant) TSRMLS_CC);
}
}
} else {
key--;
if (!zend_get_special_constant(Z_STRVAL(key->constant), Z_STRLEN(key->constant), &c TSRMLS_CC)) {
return NULL;
}
c = zend_get_special_constant(Z_STRVAL(key->constant), Z_STRLEN(key->constant) TSRMLS_CC);
}
}
}
@ -469,53 +459,51 @@ zend_constant *zend_quick_get_constant(const zend_literal *key, ulong flags TSRM
ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)
{
char *lowercase_name = NULL;
char *name;
zend_string *lowercase_name = NULL;
zend_string *name;
int ret = SUCCESS;
ulong chash;
#if 0
printf("Registering constant for module %d\n", c->module_number);
#endif
if (!(c->flags & CONST_CS)) {
/* keep in mind that c->name_len already contains the '\0' */
lowercase_name = estrndup(c->name, c->name_len-1);
zend_str_tolower(lowercase_name, c->name_len-1);
lowercase_name = (char*)zend_new_interned_string(lowercase_name, c->name_len, 1 TSRMLS_CC);
//??? /* keep in mind that c->name_len already contains the '\0' */
lowercase_name = STR_ALLOC(c->name->len, 0);
zend_str_tolower_copy(lowercase_name->val, c->name->val, c->name->len);
lowercase_name = zend_new_interned_string(lowercase_name TSRMLS_CC);
name = lowercase_name;
} else {
char *slash = strrchr(c->name, '\\');
char *slash = strrchr(c->name->val, '\\');
if (slash) {
lowercase_name = estrndup(c->name, c->name_len-1);
zend_str_tolower(lowercase_name, slash-c->name);
lowercase_name = (char*)zend_new_interned_string(lowercase_name, c->name_len, 1 TSRMLS_CC);
lowercase_name = STR_ALLOC(c->name->len, 0);
zend_str_tolower_copy(lowercase_name->val, c->name->val, c->name->len);
lowercase_name = zend_new_interned_string(lowercase_name TSRMLS_CC);
name = lowercase_name;
} else {
name = c->name;
}
}
chash = str_hash(name, c->name_len-1);
/* Check if the user is trying to define the internal pseudo constant name __COMPILER_HALT_OFFSET__ */
if ((c->name_len == sizeof("__COMPILER_HALT_OFFSET__")
&& !memcmp(name, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1))
|| zend_hash_quick_add(EG(zend_constants), name, c->name_len, chash, (void *) c, sizeof(zend_constant), NULL)==FAILURE) {
if ((c->name->len == sizeof("__COMPILER_HALT_OFFSET__")
&& !memcmp(name->val, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__")-1))
|| zend_hash_add_mem(EG(zend_constants), name, c, sizeof(zend_constant)) == NULL) {
/* The internal __COMPILER_HALT_OFFSET__ is prefixed by NULL byte */
if (c->name[0] == '\0' && c->name_len > sizeof("\0__COMPILER_HALT_OFFSET__")
&& memcmp(name, "\0__COMPILER_HALT_OFFSET__", sizeof("\0__COMPILER_HALT_OFFSET__")) == 0) {
name++;
if (c->name->val[0] == '\0' && c->name->len > sizeof("\0__COMPILER_HALT_OFFSET__")
&& memcmp(name->val, "\0__COMPILER_HALT_OFFSET__", sizeof("\0__COMPILER_HALT_OFFSET__")) == 0) {
//??? name++;
}
zend_error(E_NOTICE,"Constant %s already defined", name);
str_free(c->name);
zend_error(E_NOTICE,"Constant %s already defined", name->val);
STR_RELEASE(c->name);
if (!(c->flags & CONST_PERSISTENT)) {
zval_dtor(&c->value);
}
ret = FAILURE;
}
if (lowercase_name) {
str_efree(lowercase_name);
STR_RELEASE(lowercase_name);
}
return ret;
}

View file

@ -33,8 +33,7 @@
typedef struct _zend_constant {
zval value;
int flags;
char *name;
uint name_len;
zend_string *name;
int module_number;
} zend_constant;
@ -76,11 +75,10 @@ ZEND_API void zend_register_string_constant(const char *name, uint name_len, cha
ZEND_API void zend_register_stringl_constant(const char *name, uint name_len, char *strval, uint strlen, int flags, int module_number TSRMLS_DC);
ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC);
void zend_copy_constants(HashTable *target, HashTable *sourc);
void copy_zend_constant(zend_constant *c);
zend_constant *zend_quick_get_constant(const zend_literal *key, ulong flags TSRMLS_DC);
END_EXTERN_C()
#define ZEND_CONSTANT_DTOR (void (*)(void *)) free_zend_constant
#define ZEND_CONSTANT_DTOR (void (*)(zval *)) free_zend_constant
#endif

View file

@ -34,26 +34,29 @@ static zend_class_entry *error_exception_ce;
static zend_object_handlers default_exception_handlers;
ZEND_API void (*zend_throw_exception_hook)(zval *ex TSRMLS_DC);
void zend_exception_set_previous(zval *exception, zval *add_previous TSRMLS_DC)
void zend_exception_set_previous(zend_object *exception, zend_object *add_previous TSRMLS_DC)
{
zval *previous;
zval tmp, *previous, zv, *pzv;
if (exception == add_previous || !add_previous || !exception) {
return;
}
if (Z_TYPE_P(add_previous) != IS_OBJECT && !instanceof_function(Z_OBJCE_P(add_previous), default_exception_ce TSRMLS_CC)) {
ZVAL_OBJ(&tmp, add_previous);
if (!instanceof_function(Z_OBJCE(tmp), default_exception_ce TSRMLS_CC)) {
zend_error(E_ERROR, "Cannot set non exception as previous exception");
return;
}
while (exception && exception != add_previous && Z_OBJ_HANDLE_P(exception) != Z_OBJ_HANDLE_P(add_previous)) {
previous = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 1 TSRMLS_CC);
ZVAL_OBJ(&zv, exception);
pzv = &zv;
do {
previous = zend_read_property(default_exception_ce, pzv, "previous", sizeof("previous")-1, 1 TSRMLS_CC);
if (Z_TYPE_P(previous) == IS_NULL) {
zend_update_property(default_exception_ce, exception, "previous", sizeof("previous")-1, add_previous TSRMLS_CC);
Z_DELREF_P(add_previous);
zend_update_property(default_exception_ce, pzv, "previous", sizeof("previous")-1, &tmp TSRMLS_CC);
add_previous->gc.refcount--;
return;
}
exception = previous;
}
pzv = previous;
} while (pzv && Z_OBJ_P(pzv) != add_previous);
}
void zend_exception_save(TSRMLS_D) /* {{{ */
@ -98,9 +101,9 @@ void zend_throw_exception_internal(zval *exception TSRMLS_DC) /* {{{ */
#endif /* HAVE_DTRACE */
if (exception != NULL) {
zval *previous = EG(exception);
zend_exception_set_previous(exception, EG(exception) TSRMLS_CC);
EG(exception) = exception;
zend_object *previous = EG(exception);
zend_exception_set_previous(Z_OBJ_P(exception), EG(exception) TSRMLS_CC);
EG(exception) = Z_OBJ_P(exception);
if (previous) {
return;
}
@ -129,13 +132,14 @@ void zend_throw_exception_internal(zval *exception TSRMLS_DC) /* {{{ */
ZEND_API void zend_clear_exception(TSRMLS_D) /* {{{ */
{
if (EG(prev_exception)) {
zval_ptr_dtor(&EG(prev_exception));
//??? zval_ptr_dtor(&EG(prev_exception));
EG(prev_exception) = NULL;
}
if (!EG(exception)) {
return;
}
zval_ptr_dtor(&EG(exception));
//??? zval_ptr_dtor(&EG(exception));
EG(exception) = NULL;
EG(current_execute_data)->opline = EG(opline_before_exception);
#if ZEND_DEBUG
@ -144,37 +148,34 @@ ZEND_API void zend_clear_exception(TSRMLS_D) /* {{{ */
}
/* }}} */
static zend_object_value zend_default_exception_new_ex(zend_class_entry *class_type, int skip_top_traces TSRMLS_DC) /* {{{ */
static zend_object *zend_default_exception_new_ex(zend_class_entry *class_type, int skip_top_traces TSRMLS_DC) /* {{{ */
{
zval obj;
zend_object *object;
zval *trace;
zval trace;
Z_OBJVAL(obj) = zend_objects_new(&object, class_type TSRMLS_CC);
Z_OBJ(obj) = object = zend_objects_new(class_type TSRMLS_CC);
Z_OBJ_HT(obj) = &default_exception_handlers;
object_properties_init(object, class_type);
ALLOC_ZVAL(trace);
Z_UNSET_ISREF_P(trace);
Z_SET_REFCOUNT_P(trace, 0);
zend_fetch_debug_backtrace(trace, skip_top_traces, 0, 0 TSRMLS_CC);
zend_fetch_debug_backtrace(&trace, skip_top_traces, 0, 0 TSRMLS_CC);
zend_update_property_string(default_exception_ce, &obj, "file", sizeof("file")-1, zend_get_executed_filename(TSRMLS_C) TSRMLS_CC);
zend_update_property_long(default_exception_ce, &obj, "line", sizeof("line")-1, zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC);
zend_update_property(default_exception_ce, &obj, "trace", sizeof("trace")-1, trace TSRMLS_CC);
zend_update_property(default_exception_ce, &obj, "trace", sizeof("trace")-1, &trace TSRMLS_CC);
return Z_OBJVAL(obj);
return object;
}
/* }}} */
static zend_object_value zend_default_exception_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
static zend_object *zend_default_exception_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
{
return zend_default_exception_new_ex(class_type, 0 TSRMLS_CC);
}
/* }}} */
static zend_object_value zend_error_exception_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
static zend_object *zend_error_exception_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
{
return zend_default_exception_new_ex(class_type, 2 TSRMLS_CC);
}
@ -268,9 +269,8 @@ 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);
*return_value = *value;
zval_copy_ctor(return_value);
INIT_PZVAL(return_value);
ZVAL_DUP(return_value, value);
//??? INIT_PZVAL(return_value);
}
/* }}} */
@ -350,19 +350,21 @@ ZEND_METHOD(error_exception, getSeverity)
#define TRACE_APPEND_STR(val) \
TRACE_APPEND_STRL(val, sizeof(val)-1)
#define TRACE_APPEND_KEY(key) \
if (zend_hash_find(ht, key, sizeof(key), (void**)&tmp) == SUCCESS) { \
if (Z_TYPE_PP(tmp) != IS_STRING) { \
zend_error(E_WARNING, "Value for %s is no string", key); \
TRACE_APPEND_STR("[unknown]"); \
} else { \
TRACE_APPEND_STRL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); \
} \
}
#define TRACE_APPEND_KEY(key) do { \
tmp = zend_hash_str_find(ht, key, sizeof(key)-1); \
if (tmp) { \
if (Z_TYPE_P(tmp) != IS_STRING) { \
zend_error(E_WARNING, "Value for %s is no string", key); \
TRACE_APPEND_STR("[unknown]"); \
} else { \
TRACE_APPEND_STRL(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); \
} \
} \
} while (0)
/* }}} */
static int _build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
static int _build_trace_args(zval *arg TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
{
char **str;
int *len;
@ -376,20 +378,20 @@ static int _build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, z
* but that could cause some E_NOTICE and also damn long lines.
*/
switch (Z_TYPE_PP(arg)) {
switch (Z_TYPE_P(arg)) {
case IS_NULL:
TRACE_APPEND_STR("NULL, ");
break;
case IS_STRING: {
int l_added;
TRACE_APPEND_CHR('\'');
if (Z_STRLEN_PP(arg) > 15) {
TRACE_APPEND_STRL(Z_STRVAL_PP(arg), 15);
if (Z_STRLEN_P(arg) > 15) {
TRACE_APPEND_STRL(Z_STRVAL_P(arg), 15);
TRACE_APPEND_STR("...', ");
l_added = 15 + 6 + 1; /* +1 because of while (--l_added) */
} else {
l_added = Z_STRLEN_PP(arg);
TRACE_APPEND_STRL(Z_STRVAL_PP(arg), l_added);
l_added = Z_STRLEN_P(arg);
TRACE_APPEND_STRL(Z_STRVAL_P(arg), l_added);
TRACE_APPEND_STR("', ");
l_added += 3 + 1;
}
@ -401,7 +403,7 @@ static int _build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, z
break;
}
case IS_BOOL:
if (Z_LVAL_PP(arg)) {
if (Z_LVAL_P(arg)) {
TRACE_APPEND_STR("true, ");
} else {
TRACE_APPEND_STR("false, ");
@ -411,7 +413,7 @@ static int _build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, z
TRACE_APPEND_STR("Resource id #");
/* break; */
case IS_LONG: {
long lval = Z_LVAL_PP(arg);
long lval = Z_LVAL_P(arg);
char s_tmp[MAX_LENGTH_OF_LONG + 1];
int l_tmp = zend_sprintf(s_tmp, "%ld", lval); /* SAFE */
TRACE_APPEND_STRL(s_tmp, l_tmp);
@ -419,7 +421,7 @@ static int _build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, z
break;
}
case IS_DOUBLE: {
double dval = Z_DVAL_PP(arg);
double dval = Z_DVAL_P(arg);
char *s_tmp;
int l_tmp;
@ -435,18 +437,16 @@ static int _build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, z
TRACE_APPEND_STR("Array, ");
break;
case IS_OBJECT: {
const char *class_name;
zend_uint class_name_len;
int dup;
zend_string *class_name;
TRACE_APPEND_STR("Object(");
dup = zend_get_object_classname(*arg, &class_name, &class_name_len TSRMLS_CC);
class_name = zend_get_object_classname(arg TSRMLS_CC);
TRACE_APPEND_STRL(class_name, class_name_len);
if(!dup) {
efree((char*)class_name);
}
TRACE_APPEND_STRL(class_name->val, class_name->len);
//??? if(!dup) {
//??? efree((char*)class_name);
//??? }
TRACE_APPEND_STR("), ");
break;
@ -458,15 +458,15 @@ static int _build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, z
}
/* }}} */
static int _build_trace_string(zval **frame TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
static int _build_trace_string(zval *frame TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
{
char *s_tmp, **str;
int *len, *num;
long line;
HashTable *ht = Z_ARRVAL_PP(frame);
zval **file, **tmp;
HashTable *ht = Z_ARRVAL_P(frame);
zval *file, *tmp;
if (Z_TYPE_PP(frame) != IS_ARRAY) {
if (Z_TYPE_P(frame) != IS_ARRAY) {
zend_error(E_WARNING, "Expected array for frame %lu", hash_key->h);
return ZEND_HASH_APPLY_KEEP;
}
@ -479,14 +479,16 @@ static int _build_trace_string(zval **frame TSRMLS_DC, int num_args, va_list arg
sprintf(s_tmp, "#%d ", (*num)++);
TRACE_APPEND_STRL(s_tmp, strlen(s_tmp));
efree(s_tmp);
if (zend_hash_find(ht, "file", sizeof("file"), (void**)&file) == SUCCESS) {
if (Z_TYPE_PP(file) != IS_STRING) {
file = zend_hash_str_find(ht, "file", sizeof("file")-1);
if (file) {
if (Z_TYPE_P(file) != IS_STRING) {
zend_error(E_WARNING, "Function name is no string");
TRACE_APPEND_STR("[unknown function]");
} else{
if (zend_hash_find(ht, "line", sizeof("line"), (void**)&tmp) == SUCCESS) {
if (Z_TYPE_PP(tmp) == IS_LONG) {
line = Z_LVAL_PP(tmp);
tmp = zend_hash_str_find(ht, "line", sizeof("line")-1);
if (tmp) {
if (Z_TYPE_P(tmp) == IS_LONG) {
line = Z_LVAL_P(tmp);
} else {
zend_error(E_WARNING, "Line is no long");
line = 0;
@ -494,8 +496,8 @@ static int _build_trace_string(zval **frame TSRMLS_DC, int num_args, va_list arg
} else {
line = 0;
}
s_tmp = emalloc(Z_STRLEN_PP(file) + MAX_LENGTH_OF_LONG + 4 + 1);
sprintf(s_tmp, "%s(%ld): ", Z_STRVAL_PP(file), line);
s_tmp = emalloc(Z_STRLEN_P(file) + MAX_LENGTH_OF_LONG + 4 + 1);
sprintf(s_tmp, "%s(%ld): ", Z_STRVAL_P(file), line);
TRACE_APPEND_STRL(s_tmp, strlen(s_tmp));
efree(s_tmp);
}
@ -506,10 +508,11 @@ static int _build_trace_string(zval **frame TSRMLS_DC, int num_args, va_list arg
TRACE_APPEND_KEY("type");
TRACE_APPEND_KEY("function");
TRACE_APPEND_CHR('(');
if (zend_hash_find(ht, "args", sizeof("args"), (void**)&tmp) == SUCCESS) {
if (Z_TYPE_PP(tmp) == IS_ARRAY) {
tmp = zend_hash_str_find(ht, "args", sizeof("args")-1);
if (tmp) {
if (Z_TYPE_P(tmp) == IS_ARRAY) {
int last_len = *len;
zend_hash_apply_with_arguments(Z_ARRVAL_PP(tmp) TSRMLS_CC, (apply_func_args_t)_build_trace_args, 2, str, len);
zend_hash_apply_with_arguments(Z_ARRVAL_P(tmp) TSRMLS_CC, (apply_func_args_t)_build_trace_args, 2, str, len);
if (last_len != *len) {
*len -= 2; /* remove last ', ' */
}
@ -544,7 +547,8 @@ ZEND_METHOD(exception, getTraceAsString)
efree(s_tmp);
res[res_len] = '\0';
RETURN_STRINGL(res, res_len, 0);
//??? RETURN_STRINGL(res, res_len, 0);
RETURN_STRINGL(res, res_len);
}
/* }}} */
@ -587,7 +591,7 @@ ZEND_METHOD(exception, __toString)
str = estrndup("", 0);
exception = getThis();
ZVAL_STRINGL(&fname, "gettraceasstring", sizeof("gettraceasstring")-1, 1);
ZVAL_STRINGL(&fname, "gettraceasstring", sizeof("gettraceasstring")-1);
while (exception && Z_TYPE_P(exception) == IS_OBJECT) {
prev_str = str;
@ -601,20 +605,20 @@ ZEND_METHOD(exception, __toString)
fci.size = sizeof(fci);
fci.function_table = &Z_OBJCE_P(exception)->function_table;
fci.function_name = &fname;
ZVAL_COPY_VALUE(&fci.function_name, &fname);
fci.symbol_table = NULL;
fci.object_ptr = exception;
fci.retval_ptr_ptr = &trace;
//??? fci.retval_ptr_ptr = &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_P(trace) != IS_STRING) {
//??? zval_ptr_dtor(&trace);
//??? trace = NULL;
//??? }
if (Z_STRLEN(message) > 0) {
len = zend_spprintf(&str, 0, "exception '%s' with message '%s' in %s:%ld\nStack trace:\n%s%s%s",
@ -634,9 +638,9 @@ 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);
}
//??? if (trace) {
//??? zval_ptr_dtor(&trace);
//??? }
}
zval_dtor(&fname);
@ -645,7 +649,8 @@ ZEND_METHOD(exception, __toString)
* the result in uncaught exception handlers without memleaks. */
zend_update_property_string(default_exception_ce, getThis(), "string", sizeof("string")-1, str TSRMLS_CC);
RETURN_STRINGL(str, len, 0);
//??? RETURN_STRINGL(str, len, 0);
RETURN_STRINGL(str, len);
}
/* }}} */
@ -714,7 +719,7 @@ void zend_register_default_exception(TSRMLS_D) /* {{{ */
zend_declare_property_null(default_exception_ce, "previous", sizeof("previous")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
INIT_CLASS_ENTRY(ce, "ErrorException", error_exception_functions);
error_exception_ce = zend_register_internal_class_ex(&ce, default_exception_ce, NULL TSRMLS_CC);
error_exception_ce = zend_register_internal_class_ex(&ce, default_exception_ce TSRMLS_CC);
error_exception_ce->create_object = zend_error_exception_new;
zend_declare_property_long(error_exception_ce, "severity", sizeof("severity")-1, E_ERROR, ZEND_ACC_PROTECTED TSRMLS_CC);
}
@ -732,11 +737,10 @@ ZEND_API zend_class_entry *zend_get_error_exception(TSRMLS_D) /* {{{ */
}
/* }}} */
ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, const char *message, long code TSRMLS_DC) /* {{{ */
ZEND_API zend_object *zend_throw_exception(zend_class_entry *exception_ce, const char *message, long code TSRMLS_DC) /* {{{ */
{
zval *ex;
zval ex;
MAKE_STD_ZVAL(ex);
if (exception_ce) {
if (!instanceof_function(exception_ce, default_exception_ce TSRMLS_CC)) {
zend_error(E_NOTICE, "Exceptions must be derived from the Exception base class");
@ -745,41 +749,43 @@ ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, const char
} else {
exception_ce = default_exception_ce;
}
object_init_ex(ex, exception_ce);
object_init_ex(&ex, exception_ce);
if (message) {
zend_update_property_string(default_exception_ce, ex, "message", sizeof("message")-1, message TSRMLS_CC);
zend_update_property_string(default_exception_ce, &ex, "message", sizeof("message")-1, message TSRMLS_CC);
}
if (code) {
zend_update_property_long(default_exception_ce, ex, "code", sizeof("code")-1, code TSRMLS_CC);
zend_update_property_long(default_exception_ce, &ex, "code", sizeof("code")-1, code TSRMLS_CC);
}
zend_throw_exception_internal(ex TSRMLS_CC);
return ex;
zend_throw_exception_internal(&ex TSRMLS_CC);
return Z_OBJ(ex);
}
/* }}} */
ZEND_API zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, const char *format, ...) /* {{{ */
ZEND_API zend_object *zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, const char *format, ...) /* {{{ */
{
va_list arg;
char *message;
zval *zexception;
zend_object *obj;
va_start(arg, format);
zend_vspprintf(&message, 0, format, arg);
va_end(arg);
zexception = zend_throw_exception(exception_ce, message, code TSRMLS_CC);
obj = zend_throw_exception(exception_ce, message, code TSRMLS_CC);
efree(message);
return zexception;
return obj;
}
/* }}} */
ZEND_API zval * zend_throw_error_exception(zend_class_entry *exception_ce, const char *message, long code, int severity TSRMLS_DC) /* {{{ */
ZEND_API zend_object *zend_throw_error_exception(zend_class_entry *exception_ce, const char *message, long code, int severity TSRMLS_DC) /* {{{ */
{
zval *ex = zend_throw_exception(exception_ce, message, code TSRMLS_CC);
zend_update_property_long(default_exception_ce, ex, "severity", sizeof("severity")-1, severity TSRMLS_CC);
return ex;
zval ex;
zend_object *obj = zend_throw_exception(exception_ce, message, code TSRMLS_CC);
ZVAL_OBJ(&ex, obj);
zend_update_property_long(default_exception_ce, &ex, "severity", sizeof("severity")-1, severity TSRMLS_CC);
return obj;
}
/* }}} */
@ -794,29 +800,36 @@ static void zend_error_va(int type, const char *file, uint lineno, const char *f
/* }}} */
/* This function doesn't return if it uses E_ERROR */
ZEND_API void zend_exception_error(zval *exception, int severity TSRMLS_DC) /* {{{ */
ZEND_API void zend_exception_error(zend_object *ex, int severity TSRMLS_DC) /* {{{ */
{
zend_class_entry *ce_exception = Z_OBJCE_P(exception);
zval exception;
zend_class_entry *ce_exception;
ZVAL_OBJ(&exception, ex);
ce_exception = Z_OBJCE(exception);
if (instanceof_function(ce_exception, default_exception_ce TSRMLS_CC)) {
zval *str, *file, *line;
zval tmp, *str, *file, *line;
EG(exception) = NULL;
zend_call_method_with_0_params(&exception, ce_exception, NULL, "__tostring", &str);
zend_call_method_with_0_params(&exception, ce_exception, NULL, "__tostring", &tmp);
if (!EG(exception)) {
if (Z_TYPE_P(str) != IS_STRING) {
zend_error(E_WARNING, "%s::__toString() must return a string", ce_exception->name);
if (Z_TYPE(tmp) != IS_STRING) {
zend_error(E_WARNING, "%s::__toString() must return a string", ce_exception->name->val);
} else {
zend_update_property_string(default_exception_ce, exception, "string", sizeof("string")-1, EG(exception) ? ce_exception->name : Z_STRVAL_P(str) TSRMLS_CC);
zend_update_property_string(default_exception_ce, &exception, "string", sizeof("string")-1, EG(exception) ? ce_exception->name->val : Z_STRVAL(tmp) TSRMLS_CC);
}
}
zval_ptr_dtor(&str);
zval_ptr_dtor(&tmp);
if (EG(exception)) {
zval zv;
ZVAL_OBJ(&zv, EG(exception));
/* do the best we can to inform about the inner exception */
if (instanceof_function(ce_exception, default_exception_ce TSRMLS_CC)) {
file = zend_read_property(default_exception_ce, EG(exception), "file", sizeof("file")-1, 1 TSRMLS_CC);
line = zend_read_property(default_exception_ce, EG(exception), "line", sizeof("line")-1, 1 TSRMLS_CC);
file = zend_read_property(default_exception_ce, &zv, "file", sizeof("file")-1, 1 TSRMLS_CC);
line = zend_read_property(default_exception_ce, &zv, "line", sizeof("line")-1, 1 TSRMLS_CC);
convert_to_string(file);
file = (Z_STRLEN_P(file) > 0) ? file : NULL;
@ -825,12 +838,12 @@ ZEND_API void zend_exception_error(zval *exception, int severity TSRMLS_DC) /* {
file = NULL;
line = NULL;
}
zend_error_va(E_WARNING, file ? Z_STRVAL_P(file) : NULL, line ? Z_LVAL_P(line) : 0, "Uncaught %s in exception handling during call to %s::__tostring()", Z_OBJCE_P(EG(exception))->name, ce_exception->name);
zend_error_va(E_WARNING, file ? Z_STRVAL_P(file) : NULL, line ? Z_LVAL_P(line) : 0, "Uncaught %s in exception handling during call to %s::__tostring()", Z_OBJCE(zv)->name->val, ce_exception->name->val);
}
str = zend_read_property(default_exception_ce, exception, "string", sizeof("string")-1, 1 TSRMLS_CC);
file = zend_read_property(default_exception_ce, exception, "file", sizeof("file")-1, 1 TSRMLS_CC);
line = zend_read_property(default_exception_ce, exception, "line", sizeof("line")-1, 1 TSRMLS_CC);
str = zend_read_property(default_exception_ce, &exception, "string", sizeof("string")-1, 1 TSRMLS_CC);
file = zend_read_property(default_exception_ce, &exception, "file", sizeof("file")-1, 1 TSRMLS_CC);
line = zend_read_property(default_exception_ce, &exception, "line", sizeof("line")-1, 1 TSRMLS_CC);
convert_to_string(str);
convert_to_string(file);
@ -838,7 +851,7 @@ ZEND_API void zend_exception_error(zval *exception, int severity TSRMLS_DC) /* {
zend_error_va(severity, (Z_STRLEN_P(file) > 0) ? Z_STRVAL_P(file) : NULL, Z_LVAL_P(line), "Uncaught %s\n thrown", Z_STRVAL_P(str));
} else {
zend_error(severity, "Uncaught exception '%s'", ce_exception->name);
zend_error(severity, "Uncaught exception '%s'", ce_exception->name->val);
}
}
/* }}} */

View file

@ -26,7 +26,7 @@
BEGIN_EXTERN_C()
ZEND_API void zend_exception_set_previous(zval *exception, zval *add_previous TSRMLS_DC);
ZEND_API void zend_exception_set_previous(zend_object *exception, zend_object *add_previous TSRMLS_DC);
ZEND_API void zend_exception_save(TSRMLS_D);
ZEND_API void zend_exception_restore(TSRMLS_D);
@ -40,17 +40,17 @@ ZEND_API void zend_register_default_classes(TSRMLS_D);
/* exception_ce NULL or zend_exception_get_default() or a derived class
* message NULL or the message of the exception */
ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, const char *message, long code TSRMLS_DC);
ZEND_API zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, const char *format, ...);
ZEND_API zend_object *zend_throw_exception(zend_class_entry *exception_ce, const char *message, long code TSRMLS_DC);
ZEND_API zend_object *zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, const char *format, ...);
ZEND_API void zend_throw_exception_object(zval *exception TSRMLS_DC);
ZEND_API void zend_clear_exception(TSRMLS_D);
ZEND_API zval * zend_throw_error_exception(zend_class_entry *exception_ce, const char *message, long code, int severity TSRMLS_DC);
ZEND_API zend_object *zend_throw_error_exception(zend_class_entry *exception_ce, const char *message, long code, int severity TSRMLS_DC);
extern ZEND_API void (*zend_throw_exception_hook)(zval *ex TSRMLS_DC);
/* show an exception using zend_error(severity,...), severity should be E_ERROR */
ZEND_API void zend_exception_error(zval *exception, int severity TSRMLS_DC);
ZEND_API void zend_exception_error(zend_object *exception, int severity TSRMLS_DC);
/* do not export, in php it's available thru spprintf directly */
int zend_spprintf(char **message, int max_len, const char *format, ...);

File diff suppressed because it is too large Load diff

View file

@ -27,26 +27,25 @@
#include "zend_operators.h"
#include "zend_variables.h"
typedef union _temp_variable {
zval tmp_var;
struct {
zval **ptr_ptr;
zval *ptr;
zend_bool fcall_returned_reference;
} var;
struct {
zval **ptr_ptr; /* shared with var.ptr_ptr */
zval *str;
zend_uint offset;
} str_offset;
struct {
zval **ptr_ptr; /* shared with var.ptr_ptr */
zval *ptr; /* shared with var.ptr */
HashPointer fe_pos;
} fe;
zend_class_entry *class_entry;
} temp_variable;
//???typedef union _temp_variable {
//??? zval tmp_var;
//??? struct {
//??? zval **ptr_ptr;
//??? zval *ptr;
//??? zend_bool fcall_returned_reference;
//??? } var;
//??? struct {
//??? zval **ptr_ptr; /* shared with var.ptr_ptr */
//??? zval *str;
//??? zend_uint offset;
//??? } str_offset;
//??? struct {
//??? zval **ptr_ptr; /* shared with var.ptr_ptr */
//??? zval *ptr; /* shared with var.ptr */
//??? HashPointer fe_pos;
//??? } fe;
//??? zend_class_entry *class_entry;
//???} temp_variable;
BEGIN_EXTERN_C()
struct _zend_fcall_info;
@ -61,14 +60,14 @@ ZEND_API void zend_execute(zend_op_array *op_array TSRMLS_DC);
ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS_DC);
ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, struct _zend_fcall_info *fci, int return_value_used TSRMLS_DC);
ZEND_API int zend_is_true(zval *op TSRMLS_DC);
ZEND_API int zend_lookup_class(const char *name, int name_length, zend_class_entry ***ce TSRMLS_DC);
ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_literal *key, int use_autoload, zend_class_entry ***ce TSRMLS_DC);
ZEND_API zend_class_entry *zend_lookup_class(zend_string *name TSRMLS_DC);
ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zend_literal *key, int use_autoload TSRMLS_DC);
ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC);
ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *string_name TSRMLS_DC);
ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC);
ZEND_API int zend_eval_stringl_ex(char *str, int str_len, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC);
ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, ulong fetch_type, const char **class_name, zend_class_entry **pce TSRMLS_DC);
ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, ulong fetch_type, char **class_name, zend_class_entry **pce TSRMLS_DC);
ZEND_API int zend_verify_arg_error(int error_type, const zend_function *zf, zend_uint arg_num, const char *need_msg, const char *need_kind, const char *given_msg, const char *given_kind TSRMLS_DC);
static zend_always_inline void i_zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC TSRMLS_DC)
@ -79,8 +78,11 @@ static zend_always_inline void i_zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC
zval_dtor(zval_ptr);
efree_rel(zval_ptr);
} else {
if (Z_REFCOUNT_P(zval_ptr) == 1) {
Z_UNSET_ISREF_P(zval_ptr);
if (Z_REFCOUNT_P(zval_ptr) == 1 && Z_TYPE_P(zval_ptr) == IS_REFERENCE) {
/* convert reference to regular value */
zend_reference *ref = Z_REF_P(zval_ptr);
*zval_ptr = ref->val;
efree_rel(ref);
}
GC_ZVAL_CHECK_POSSIBLE_ROOT(zval_ptr);
@ -95,8 +97,11 @@ static zend_always_inline void i_zval_ptr_dtor_nogc(zval *zval_ptr ZEND_FILE_LIN
zval_dtor(zval_ptr);
efree_rel(zval_ptr);
} else {
if (Z_REFCOUNT_P(zval_ptr) == 1) {
Z_UNSET_ISREF_P(zval_ptr);
if (Z_REFCOUNT_P(zval_ptr) == 1 && Z_TYPE_P(zval_ptr) == IS_REFERENCE) {
/* convert reference to regular value */
zend_reference *ref = Z_REF_P(zval_ptr);
*zval_ptr = ref->val;
efree_rel(ref);
}
}
}
@ -142,7 +147,7 @@ static zend_always_inline int i_zend_is_true(zval *op TSRMLS_DC)
/* for safety - avoid loop */
convert_to_boolean(tmp);
result = Z_LVAL_P(tmp);
zval_ptr_dtor(&tmp);
zval_ptr_dtor(tmp);
break;
}
}
@ -156,22 +161,22 @@ static zend_always_inline int i_zend_is_true(zval *op TSRMLS_DC)
return result;
}
ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC);
ZEND_API int zval_update_constant_inline_change(zval **pp, void *arg TSRMLS_DC);
ZEND_API int zval_update_constant_no_inline_change(zval **pp, void *arg TSRMLS_DC);
ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC);
ZEND_API int zval_update_constant(zval *pp, void *arg TSRMLS_DC);
ZEND_API int zval_update_constant_inline_change(zval *pp, void *arg TSRMLS_DC);
ZEND_API int zval_update_constant_no_inline_change(zval *pp, void *arg TSRMLS_DC);
ZEND_API int zval_update_constant_ex(zval *pp, void *arg, zend_class_entry *scope TSRMLS_DC);
/* dedicated Zend executor functions - do not use! */
#define ZEND_VM_STACK_PAGE_SIZE ((16 * 1024) - 16)
struct _zend_vm_stack {
void **top;
void **end;
zval *top;
zval *end;
zend_vm_stack prev;
};
#define ZEND_VM_STACK_ELEMETS(stack) \
((void**)(((char*)(stack)) + ZEND_MM_ALIGNED_SIZE(sizeof(struct _zend_vm_stack))))
((zval*)(((char*)(stack)) + ZEND_MM_ALIGNED_SIZE(sizeof(struct _zend_vm_stack))))
#define ZEND_VM_STACK_GROW_IF_NEEDED(count) \
do { \
@ -213,124 +218,86 @@ static zend_always_inline void zend_vm_stack_extend(int count TSRMLS_DC)
EG(argument_stack) = p;
}
static zend_always_inline void **zend_vm_stack_top(TSRMLS_D)
static zend_always_inline zval *zend_vm_stack_top(TSRMLS_D)
{
return EG(argument_stack)->top;
}
static zend_always_inline void zend_vm_stack_push(void *ptr TSRMLS_DC)
static zend_always_inline void zend_vm_stack_push(zval *ptr TSRMLS_DC)
{
*(EG(argument_stack)->top++) = ptr;
*(EG(argument_stack)->top++) = *ptr;
}
static zend_always_inline void *zend_vm_stack_pop(TSRMLS_D)
static zend_always_inline zval *zend_vm_stack_pop(TSRMLS_D)
{
void *el = *(--EG(argument_stack)->top);
return el;
return --EG(argument_stack)->top;
}
static zend_always_inline void *zend_vm_stack_alloc(size_t size TSRMLS_DC)
{
void *ret;
zval *ret;
int count = (size + (sizeof(zval) - 1)) / sizeof(zval);
size = (size + (sizeof(void*) - 1)) / sizeof(void*);
/* the following comparison must be optimized out at compile time */
if (ZEND_MM_ALIGNMENT > sizeof(void*)) {
int extra = (ZEND_MM_ALIGNMENT - ((zend_uintptr_t)EG(argument_stack)->top & (ZEND_MM_ALIGNMENT - 1))) / sizeof(void*);
if (UNEXPECTED(size + extra + ZEND_MM_ALIGNED_SIZE(sizeof(void*)) / sizeof(void*) >
(zend_uintptr_t)(EG(argument_stack)->end - EG(argument_stack)->top))) {
zend_vm_stack_extend(size TSRMLS_CC);
} else {
void **old_top = EG(argument_stack)->top;
EG(argument_stack)->top += extra;
/* store old top on the stack */
*EG(argument_stack)->top = (void*)old_top;
EG(argument_stack)->top += ZEND_MM_ALIGNED_SIZE(sizeof(void*)) / sizeof(void*);
}
} else {
ZEND_VM_STACK_GROW_IF_NEEDED((int)size);
}
ZEND_VM_STACK_GROW_IF_NEEDED(count);
ret = (void*)EG(argument_stack)->top;
EG(argument_stack)->top += size;
EG(argument_stack)->top += count;
return ret;
}
static zend_always_inline void** zend_vm_stack_frame_base(zend_execute_data *ex)
static zend_always_inline zval* zend_vm_stack_frame_base(zend_execute_data *ex)
{
return (void**)((char*)ex->call_slots +
ZEND_MM_ALIGNED_SIZE(sizeof(call_slot)) * ex->op_array->nested_calls);
}
static zend_always_inline void zend_vm_stack_free_int(void *ptr TSRMLS_DC)
{
if (UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (void**)ptr)) {
zend_vm_stack p = EG(argument_stack);
EG(argument_stack) = p->prev;
efree(p);
} else {
EG(argument_stack)->top = (void**)ptr;
}
//??? return (void**)((char*)ex->call_slots +
//??? ZEND_MM_ALIGNED_SIZE(sizeof(call_slot)) * ex->op_array->nested_calls);
return NULL;
}
static zend_always_inline void zend_vm_stack_free(void *ptr TSRMLS_DC)
{
if (UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (void**)ptr)) {
if (UNEXPECTED((void*)ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == ptr)) {
zend_vm_stack p = EG(argument_stack);
EG(argument_stack) = p->prev;
efree(p);
} else {
/* the following comparison must be optimized out at compile time */
if (ZEND_MM_ALIGNMENT > sizeof(void*)) {
ptr = (void*)(((char*)ptr) - ZEND_MM_ALIGNED_SIZE(sizeof(void*)));
EG(argument_stack)->top = *(void***)ptr;
} else {
EG(argument_stack)->top = (void**)ptr;
}
EG(argument_stack)->top = (zval*)ptr;
}
}
static zend_always_inline void zend_vm_stack_clear_multiple(int nested TSRMLS_DC)
{
void **p = EG(argument_stack)->top - 1;
void **end = p - (int)(zend_uintptr_t)*p;
zval *p = EG(argument_stack)->top - 1;
zval *end = p - Z_LVAL_P(p);
while (p != end) {
zval *q = (zval *) *(--p);
*p = NULL;
i_zval_ptr_dtor(q ZEND_FILE_LINE_CC TSRMLS_CC);
p--;
i_zval_ptr_dtor(p ZEND_FILE_LINE_CC TSRMLS_CC);
}
if (nested) {
EG(argument_stack)->top = p;
} else {
zend_vm_stack_free_int(p TSRMLS_CC);
zend_vm_stack_free(p TSRMLS_CC);
}
}
static zend_always_inline int zend_vm_stack_get_args_count_ex(zend_execute_data *ex)
{
if (ex) {
void **p = ex->function_state.arguments;
return (int)(zend_uintptr_t) *p;
zval *p = ex->function_state.arguments;
return Z_LVAL_P(p);
} else {
return 0;
}
}
static zend_always_inline zval** zend_vm_stack_get_arg_ex(zend_execute_data *ex, int requested_arg)
static zend_always_inline zval* zend_vm_stack_get_arg_ex(zend_execute_data *ex, int requested_arg)
{
void **p = ex->function_state.arguments;
int arg_count = (int)(zend_uintptr_t) *p;
zval *p = ex->function_state.arguments;
int arg_count = Z_LVAL_P(p);
if (UNEXPECTED(requested_arg > arg_count)) {
return NULL;
}
return (zval**)p - arg_count + requested_arg - 1;
return (zval*)p - arg_count + requested_arg - 1;
}
static zend_always_inline int zend_vm_stack_get_args_count(TSRMLS_D)
@ -338,7 +305,7 @@ static zend_always_inline int zend_vm_stack_get_args_count(TSRMLS_D)
return zend_vm_stack_get_args_count_ex(EG(current_execute_data)->prev_execute_data);
}
static zend_always_inline zval** zend_vm_stack_get_arg(int requested_arg TSRMLS_DC)
static zend_always_inline zval* zend_vm_stack_get_arg(int requested_arg TSRMLS_DC)
{
return zend_vm_stack_get_arg_ex(EG(current_execute_data)->prev_execute_data, requested_arg);
}
@ -356,8 +323,8 @@ ZEND_API zend_bool zend_is_executing(TSRMLS_D);
ZEND_API void zend_set_timeout(long seconds, int reset_signals);
ZEND_API void zend_unset_timeout(TSRMLS_D);
ZEND_API void zend_timeout(int dummy);
ZEND_API zend_class_entry *zend_fetch_class(const char *class_name, uint class_name_len, int fetch_type TSRMLS_DC);
ZEND_API zend_class_entry *zend_fetch_class_by_name(const char *class_name, uint class_name_len, const zend_literal *key, int fetch_type TSRMLS_DC);
ZEND_API zend_class_entry *zend_fetch_class(zend_string *class_name, int fetch_type TSRMLS_DC);
ZEND_API zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, const zend_literal *key, int fetch_type TSRMLS_DC);
void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC);
#ifdef ZEND_WIN32
@ -367,17 +334,14 @@ void zend_shutdown_timeout_thread(void);
#define WM_UNREGISTER_ZEND_TIMEOUT (WM_USER+2)
#endif
#define zendi_zval_copy_ctor(p) zval_copy_ctor(&(p))
#define zendi_zval_dtor(p) zval_dtor(&(p))
#define active_opline (*EG(opline_ptr))
/* The following tries to resolve the classname of a zval of type object.
* Since it is slow it should be only used in error messages.
*/
#define Z_OBJ_CLASS_NAME_P(zval) ((zval) && Z_TYPE_P(zval) == IS_OBJECT && Z_OBJ_HT_P(zval)->get_class_entry != NULL && Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC) ? Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC)->name : "")
#define Z_OBJ_CLASS_NAME_P(zval) ((zval) && Z_TYPE_P(zval) == IS_OBJECT && Z_OBJ_HT_P(zval)->get_class_entry != NULL && Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC) ? Z_OBJ_HT_P(zval)->get_class_entry(zval TSRMLS_CC)->name->val : "")
ZEND_API zval** zend_get_compiled_variable_value(const zend_execute_data *execute_data_ptr, zend_uint var);
ZEND_API zval* zend_get_compiled_variable_value(const zend_execute_data *execute_data_ptr, zend_uint var);
#define ZEND_USER_OPCODE_CONTINUE 0 /* execute next opcode */
#define ZEND_USER_OPCODE_RETURN 1 /* exit from executor (return from function) */
@ -397,7 +361,6 @@ typedef struct _zend_free_op {
} zend_free_op;
ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC);
ZEND_API zval **zend_get_zval_ptr_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC);
ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS);

File diff suppressed because it is too large Load diff

View file

@ -30,6 +30,18 @@ ZEND_API int gc_globals_id;
ZEND_API zend_gc_globals gc_globals;
#endif
#define GC_REMOVE_FROM_BUFFER(current) \
gc_remove_from_buffer((current) TSRMLS_CC)
static zend_always_inline void gc_remove_from_buffer(gc_root_buffer *root TSRMLS_DC)
{
root->next->prev = root->prev;
root->prev->next = root->next;
root->prev = GC_G(unused);
GC_G(unused) = root;
GC_BENCH_DEC(root_buf_length);
}
static void root_buffer_dtor(zend_gc_globals *gc_globals TSRMLS_DC)
{
if (gc_globals->buf) {
@ -108,7 +120,7 @@ ZEND_API void gc_reset(TSRMLS_D)
if (GC_G(buf)) {
GC_G(unused) = NULL;
GC_G(first_unused) = GC_G(buf);
GC_G(first_unused) = GC_G(buf) + 1;
GC_G(zval_to_free) = NULL;
} else {
@ -127,29 +139,23 @@ ZEND_API void gc_init(TSRMLS_D)
}
}
ZEND_API void gc_zval_possible_root(zval *zv TSRMLS_DC)
ZEND_API void gc_zval_possible_root(zend_refcounted *ref TSRMLS_DC)
{
if (UNEXPECTED(GC_G(free_list) != NULL &&
GC_ZVAL_ADDRESS(zv) != NULL &&
GC_ZVAL_GET_COLOR(zv) == GC_BLACK) &&
(GC_ZVAL_ADDRESS(zv) < GC_G(buf) ||
GC_ZVAL_ADDRESS(zv) >= GC_G(last_unused))) {
GC_ADDRESS(ref->u.v.buffer) &&
GC_GET_COLOR(ref->u.v.buffer) == GC_BLACK &&
GC_ADDRESS(ref->u.v.buffer) >= GC_G(last_unused) - GC_G(buf))) {
/* The given zval is a garbage that is going to be deleted by
* currently running GC */
return;
}
if (zv->type == IS_OBJECT) {
GC_ZOBJ_CHECK_POSSIBLE_ROOT(zv);
return;
}
GC_BENCH_INC(zval_possible_root);
if (GC_ZVAL_GET_COLOR(zv) != GC_PURPLE) {
GC_ZVAL_SET_PURPLE(zv);
if (GC_GET_COLOR(ref->u.v.buffer) != GC_PURPLE) {
GC_SET_PURPLE(ref->u.v.buffer);
if (!GC_ZVAL_ADDRESS(zv)) {
if (!GC_ADDRESS(ref->u.v.buffer)) {
gc_root_buffer *newRoot = GC_G(unused);
if (newRoot) {
@ -159,17 +165,17 @@ ZEND_API void gc_zval_possible_root(zval *zv TSRMLS_DC)
GC_G(first_unused)++;
} else {
if (!GC_G(gc_enabled)) {
GC_ZVAL_SET_BLACK(zv);
GC_SET_BLACK(ref->u.v.buffer);
return;
}
zv->refcount__gc++;
ref->refcount++;
gc_collect_cycles(TSRMLS_C);
zv->refcount__gc--;
ref->refcount--;
newRoot = GC_G(unused);
if (!newRoot) {
return;
}
GC_ZVAL_SET_PURPLE(zv);
GC_SET_PURPLE(ref->u.v.buffer);
GC_G(unused) = newRoot->prev;
}
@ -178,10 +184,9 @@ ZEND_API void gc_zval_possible_root(zval *zv TSRMLS_DC)
GC_G(roots).next->prev = newRoot;
GC_G(roots).next = newRoot;
GC_ZVAL_SET_ADDRESS(zv, newRoot);
GC_SET_ADDRESS(ref->u.v.buffer, newRoot - GC_G(buf));
newRoot->handle = 0;
newRoot->u.pz = zv;
newRoot->ref = ref;
GC_BENCH_INC(zval_buffered);
GC_BENCH_INC(root_buf_length);
@ -190,6 +195,8 @@ ZEND_API void gc_zval_possible_root(zval *zv TSRMLS_DC)
}
}
//???
#if 0
ZEND_API void gc_zobj_possible_root(zval *zv TSRMLS_DC)
{
struct _store_object *obj;
@ -245,33 +252,37 @@ ZEND_API void gc_zobj_possible_root(zval *zv TSRMLS_DC)
}
}
}
#endif
ZEND_API void gc_remove_zval_from_buffer(zval *zv TSRMLS_DC)
ZEND_API void gc_remove_zval_from_buffer(zend_refcounted *ref TSRMLS_DC)
{
gc_root_buffer* root_buffer = GC_ADDRESS(((zval_gc_info*)zv)->u.buffered);
//??? gc_root_buffer* root_buffer = GC_ADDRESS(ref->u.v.buffer);
if (UNEXPECTED(GC_G(free_list) != NULL &&
GC_ZVAL_GET_COLOR(zv) == GC_BLACK) &&
(GC_ZVAL_ADDRESS(zv) < GC_G(buf) ||
GC_ZVAL_ADDRESS(zv) >= GC_G(last_unused))) {
GC_GET_COLOR(ref->u.v.buffer) == GC_BLACK &&
GC_ADDRESS(ref->u.v.buffer) >= GC_G(last_unused) - GC_G(buf))) {
/* The given zval is a garbage that is going to be deleted by
* currently running GC */
if (GC_G(next_to_free) == (zval_gc_info*)zv) {
GC_G(next_to_free) = ((zval_gc_info*)zv)->u.next;
}
//??? if (GC_G(next_to_free) == (zval_gc_info*)zv) {
//??? GC_G(next_to_free) = ((zval_gc_info*)zv)->u.next;
//??? }
return;
}
GC_BENCH_INC(zval_remove_from_buffer);
GC_REMOVE_FROM_BUFFER(root_buffer);
((zval_gc_info*)zv)->u.buffered = NULL;
GC_REMOVE_FROM_BUFFER(GC_G(buf) + GC_ADDRESS(ref->u.v.buffer));
ref->u.v.buffer = 0;
}
//???
#if 0
static void zval_scan_black(zval *pz TSRMLS_DC)
{
HashTable *ht;
uint idx;
Bucket *p;
tail_call:
p = NULL;
ht = NULL;
GC_ZVAL_SET_BLACK(pz);
if (Z_TYPE_P(pz) == IS_OBJECT && EG(objects_store).object_buckets) {
@ -306,32 +317,35 @@ tail_call:
if (!props) {
return;
}
p = props->pListHead;
ht = props;
}
}
} else if (Z_TYPE_P(pz) == IS_ARRAY) {
if (Z_ARRVAL_P(pz) != &EG(symbol_table)) {
p = Z_ARRVAL_P(pz)->pListHead;
ht = Z_ARRVAL_P(pz);
}
}
while (p != NULL) {
pz = *(zval**)p->pData;
if (!ht) return;
for (idx = 0; idx < ht->nNumUsed; idx++) {
p = ht->arData + idx;
if (!p->xData) continue;
pz = (zval*)p->xData;
if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
pz->refcount__gc++;
}
if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) {
if (p->pListNext == NULL) {
if (idx == ht->nNumUsed-1) {
goto tail_call;
} else {
zval_scan_black(pz TSRMLS_CC);
}
}
p = p->pListNext;
}
}
static void zobj_scan_black(struct _store_object *obj, zval *pz TSRMLS_DC)
{
uint idx;
Bucket *p;
zend_object_get_gc_t get_gc;
@ -356,27 +370,29 @@ static void zobj_scan_black(struct _store_object *obj, zval *pz TSRMLS_DC)
if (!props) {
return;
}
p = props->pListHead;
while (p != NULL) {
pz = *(zval**)p->pData;
for (idx = 0; idx < props->nNumUsed; idx++) {
p = props->arData + idx;
if (!p->xData) continue;
pz = (zval*)p->xData;
if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
pz->refcount__gc++;
}
if (GC_ZVAL_GET_COLOR(pz) != GC_BLACK) {
zval_scan_black(pz TSRMLS_CC);
}
p = p->pListNext;
}
}
}
static void zval_mark_grey(zval *pz TSRMLS_DC)
{
HashTable *ht;
uint idx;
Bucket *p;
tail_call:
if (GC_ZVAL_GET_COLOR(pz) != GC_GREY) {
p = NULL;
ht = NULL;
GC_BENCH_INC(zval_marked_grey);
GC_ZVAL_SET_COLOR(pz, GC_GREY);
@ -411,33 +427,36 @@ tail_call:
if (!props) {
return;
}
p = props->pListHead;
ht = props;
}
}
} else if (Z_TYPE_P(pz) == IS_ARRAY) {
if (Z_ARRVAL_P(pz) == &EG(symbol_table)) {
GC_ZVAL_SET_BLACK(pz);
} else {
p = Z_ARRVAL_P(pz)->pListHead;
ht = Z_ARRVAL_P(pz);
}
}
while (p != NULL) {
pz = *(zval**)p->pData;
if (!ht) return;
for (idx = 0; idx < ht->nNumUsed; idx++) {
p = ht->arData + idx;
if (!p->xData) continue;
pz = (zval*)p->xData;
if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
pz->refcount__gc--;
}
if (p->pListNext == NULL) {
if (idx == ht->nNumUsed-1) {
goto tail_call;
} else {
zval_mark_grey(pz TSRMLS_CC);
}
p = p->pListNext;
}
}
}
static void zobj_mark_grey(struct _store_object *obj, zval *pz TSRMLS_DC)
{
uint idx;
Bucket *p;
zend_object_get_gc_t get_gc;
@ -462,14 +481,14 @@ static void zobj_mark_grey(struct _store_object *obj, zval *pz TSRMLS_DC)
if (!props) {
return;
}
p = props->pListHead;
while (p != NULL) {
pz = *(zval**)p->pData;
for (idx = 0; idx < props->nNumUsed; idx++) {
p = props->arData + idx;
if (!p->xData) continue;
pz = (zval*)p->xData;
if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
pz->refcount__gc--;
}
zval_mark_grey(pz TSRMLS_CC);
p = p->pListNext;
}
}
}
@ -510,11 +529,13 @@ static void gc_mark_roots(TSRMLS_D)
static void zval_scan(zval *pz TSRMLS_DC)
{
HashTable *ht;
uint idx;
Bucket *p;
tail_call:
if (GC_ZVAL_GET_COLOR(pz) == GC_GREY) {
p = NULL;
ht = NULL;
if (pz->refcount__gc > 0) {
zval_scan_black(pz TSRMLS_CC);
} else {
@ -548,7 +569,7 @@ tail_call:
if (!props) {
return;
}
p = props->pListHead;
ht = props;
}
}
}
@ -556,24 +577,27 @@ tail_call:
if (Z_ARRVAL_P(pz) == &EG(symbol_table)) {
GC_ZVAL_SET_BLACK(pz);
} else {
p = Z_ARRVAL_P(pz)->pListHead;
ht = Z_ARRVAL_P(pz);
}
}
}
while (p != NULL) {
if (p->pListNext == NULL) {
pz = *(zval**)p->pData;
if (!ht) return;
for (idx = 0; idx < ht->nNumUsed; idx++) {
p = ht->arData + idx;
if (!p->xData) continue;
if (idx == ht->nNumUsed-1) {
pz = (zval*)p->xData;
goto tail_call;
} else {
zval_scan(*(zval**)p->pData TSRMLS_CC);
zval_scan((zval*)p->xData TSRMLS_CC);
}
p = p->pListNext;
}
}
}
static void zobj_scan(zval *pz TSRMLS_DC)
{
uint idx;
Bucket *p;
zend_object_get_gc_t get_gc;
@ -600,10 +624,10 @@ static void zobj_scan(zval *pz TSRMLS_DC)
if (!props) {
return;
}
p = props->pListHead;
while (p != NULL) {
zval_scan(*(zval**)p->pData TSRMLS_CC);
p = p->pListNext;
for (idx = 0; idx < props->nNumUsed; idx++) {
p = props->arData + idx;
if (!p->xData) continue;
zval_scan((zval*)p->xData TSRMLS_CC);
}
}
}
@ -632,11 +656,13 @@ static void gc_scan_roots(TSRMLS_D)
static void zval_collect_white(zval *pz TSRMLS_DC)
{
HashTable *ht;
uint idx;
Bucket *p;
tail_call:
if (((zval_gc_info*)(pz))->u.buffered == (gc_root_buffer*)GC_WHITE) {
p = NULL;
ht = NULL;
GC_ZVAL_SET_BLACK(pz);
if (Z_TYPE_P(pz) == IS_OBJECT && EG(objects_store).object_buckets) {
@ -678,12 +704,12 @@ tail_call:
if (!props) {
return;
}
p = props->pListHead;
ht = props;
}
}
} else {
if (Z_TYPE_P(pz) == IS_ARRAY) {
p = Z_ARRVAL_P(pz)->pListHead;
ht = Z_ARRVAL_P(pz);
}
}
@ -692,23 +718,27 @@ tail_call:
((zval_gc_info*)pz)->u.next = GC_G(zval_to_free);
GC_G(zval_to_free) = (zval_gc_info*)pz;
while (p != NULL) {
pz = *(zval**)p->pData;
if (!ht) return;
for (idx = 0; idx < ht->nNumUsed; idx++) {
p = ht->arData + idx;
if (!p->xData) continue;
pz = (zval*)p->xData;
if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
pz->refcount__gc++;
}
if (p->pListNext == NULL) {
if (idx == ht->nNumUsed-1) {
goto tail_call;
} else {
zval_collect_white(pz TSRMLS_CC);
}
p = p->pListNext;
}
}
}
static void zobj_collect_white(zval *pz TSRMLS_DC)
{
uint idx;
Bucket *p;
if (EG(objects_store).object_buckets) {
@ -737,14 +767,14 @@ static void zobj_collect_white(zval *pz TSRMLS_DC)
if (!props) {
return;
}
p = props->pListHead;
while (p != NULL) {
pz = *(zval**)p->pData;
for (idx = 0; idx < props->nNumUsed; idx++) {
p = props->arData + idx;
if (!p->xData) continue;
pz = (zval*)p->xData;
if (Z_TYPE_P(pz) != IS_ARRAY || Z_ARRVAL_P(pz) != &EG(symbol_table)) {
pz->refcount__gc++;
}
zval_collect_white(pz TSRMLS_CC);
p = p->pListNext;
}
}
}
@ -776,11 +806,15 @@ static void gc_collect_roots(TSRMLS_D)
current = current->next;
}
}
#endif
#define FREE_LIST_END ((zval_gc_info*)(~(zend_uintptr_t)GC_COLOR))
ZEND_API int gc_collect_cycles(TSRMLS_D)
{
//???
return 0;
#if 0
int count = 0;
if (GC_G(roots).next != &GC_G(roots)) {
@ -857,6 +891,7 @@ ZEND_API int gc_collect_cycles(TSRMLS_D)
}
return count;
#endif
}
/*

View file

@ -40,62 +40,45 @@
# define GC_BENCH_PEAK(peak, counter)
#endif
#define GC_COLOR 0x03
#define GC_COLOR 0xc000
#define GC_BLACK 0x00
#define GC_WHITE 0x01
#define GC_GREY 0x02
#define GC_PURPLE 0x03
#define GC_BLACK 0x0000
#define GC_WHITE 0x8000
#define GC_GREY 0x4000
#define GC_PURPLE 0xc000
#define GC_ADDRESS(v) \
((gc_root_buffer*)(((zend_uintptr_t)(v)) & ~GC_COLOR))
((v) & ~GC_COLOR)
#define GC_SET_ADDRESS(v, a) \
(v) = ((gc_root_buffer*)((((zend_uintptr_t)(v)) & GC_COLOR) | ((zend_uintptr_t)(a))))
do {(v) = ((v) & GC_COLOR) | (a);} while (0)
#define GC_GET_COLOR(v) \
(((zend_uintptr_t)(v)) & GC_COLOR)
#define GC_SET_COLOR(v, c) \
(v) = ((gc_root_buffer*)((((zend_uintptr_t)(v)) & ~GC_COLOR) | (c)))
do {(v) = ((v) & ~GC_COLOR) | (c);} while (0)
#define GC_SET_BLACK(v) \
(v) = ((gc_root_buffer*)(((zend_uintptr_t)(v)) & ~GC_COLOR))
do {(v) = (v) & ~GC_COLOR;} while (0)
#define GC_SET_PURPLE(v) \
(v) = ((gc_root_buffer*)(((zend_uintptr_t)(v)) | GC_PURPLE))
do {(v) = (v) | GC_COLOR;} while (0)
#define GC_ZVAL_INIT(z) \
((zval_gc_info*)(z))->u.buffered = NULL
#define GC_ZVAL_ADDRESS(v) \
GC_ADDRESS(((zval_gc_info*)(v))->u.buffered)
GC_ADDRESS(Z_GC_BUFFER_P(v))
#define GC_ZVAL_SET_ADDRESS(v, a) \
GC_SET_ADDRESS(((zval_gc_info*)(v))->u.buffered, (a))
GC_SET_ADDRESS(Z_GC_BUFFER_P(v), (a))
#define GC_ZVAL_GET_COLOR(v) \
GC_GET_COLOR(((zval_gc_info*)(v))->u.buffered)
GC_GET_COLOR(Z_GC_BUFFER_P(v))
#define GC_ZVAL_SET_COLOR(v, c) \
GC_SET_COLOR(((zval_gc_info*)(v))->u.buffered, (c))
GC_SET_COLOR(Z_GC_BUFFER_P(v), (c))
#define GC_ZVAL_SET_BLACK(v) \
GC_SET_BLACK(((zval_gc_info*)(v))->u.buffered)
GC_SET_BLACK(Z_GC_BUFFER_P(v))
#define GC_ZVAL_SET_PURPLE(v) \
GC_SET_PURPLE(((zval_gc_info*)(v))->u.buffered)
#define GC_OBJ_INIT(z) \
(z)->buffered = NULL
GC_SET_PURPLE(Z_GC_BUFFER_P(v))
typedef struct _gc_root_buffer {
struct _gc_root_buffer *prev; /* double-linked list */
struct _gc_root_buffer *next;
zend_object_handle handle; /* must be 0 for zval */
union {
zval *pz;
const zend_object_handlers *handlers;
} u;
zend_refcounted *ref;
} gc_root_buffer;
typedef struct _zval_gc_info {
zval z;
union {
gc_root_buffer *buffered;
struct _zval_gc_info *next;
} u;
} zval_gc_info;
typedef struct _zend_gc_globals {
zend_bool gc_enabled;
zend_bool gc_active;
@ -106,9 +89,9 @@ typedef struct _zend_gc_globals {
gc_root_buffer *first_unused; /* pointer to first unused buffer */
gc_root_buffer *last_unused; /* pointer to last unused buffer */
zval_gc_info *zval_to_free; /* temporary list of zvals to free */
zval_gc_info *free_list;
zval_gc_info *next_to_free;
zend_refcounted *zval_to_free; /* temporary list of zvals to free */
zend_refcounted *free_list;
zend_refcounted *next_to_free;
zend_uint gc_runs;
zend_uint collected;
@ -140,9 +123,8 @@ extern ZEND_API zend_gc_globals gc_globals;
BEGIN_EXTERN_C()
ZEND_API int gc_collect_cycles(TSRMLS_D);
ZEND_API void gc_zval_possible_root(zval *zv TSRMLS_DC);
ZEND_API void gc_zobj_possible_root(zval *zv TSRMLS_DC);
ZEND_API void gc_remove_zval_from_buffer(zval *zv TSRMLS_DC);
ZEND_API void gc_zval_possible_root(zend_refcounted *ref TSRMLS_DC);
ZEND_API void gc_remove_zval_from_buffer(zend_refcounted *ref TSRMLS_DC);
ZEND_API void gc_globals_ctor(TSRMLS_D);
ZEND_API void gc_globals_dtor(TSRMLS_D);
ZEND_API void gc_init(TSRMLS_D);
@ -152,88 +134,19 @@ END_EXTERN_C()
#define GC_ZVAL_CHECK_POSSIBLE_ROOT(z) \
gc_zval_check_possible_root((z) TSRMLS_CC)
#define GC_REMOVE_FROM_BUFFER(current) \
gc_remove_from_buffer((current) TSRMLS_CC)
#define GC_REMOVE_ZVAL_FROM_BUFFER(z) \
if (GC_ADDRESS(((zval_gc_info*)z)->u.buffered)) { \
gc_remove_zval_from_buffer(z TSRMLS_CC); \
}
#define GC_ZOBJ_CHECK_POSSIBLE_ROOT(zobject) \
do { \
if (EXPECTED(EG(objects_store).object_buckets != NULL) && \
EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(zobject)].valid) { \
gc_zobj_possible_root(zobject TSRMLS_CC); \
} \
} while (0)
#define GC_REMOVE_ZOBJ_FROM_BUFFER(obj) \
do { \
if (GC_ADDRESS((obj)->buffered) && !GC_G(gc_active)) { \
GC_BENCH_INC(zobj_remove_from_buffer); \
GC_REMOVE_FROM_BUFFER(GC_ADDRESS((obj)->buffered)); \
(obj)->buffered = NULL; \
} \
#define GC_REMOVE_ZVAL_FROM_BUFFER(z) do { \
if (GC_ZVAL_ADDRESS(z)) { \
gc_remove_zval_from_buffer(Z_COUNTED_P(z) TSRMLS_CC); \
} \
} while (0)
static zend_always_inline void gc_zval_check_possible_root(zval *z TSRMLS_DC)
{
if (z->type == IS_ARRAY || z->type == IS_OBJECT) {
gc_zval_possible_root(z TSRMLS_CC);
if (Z_TYPE_P(z) == IS_ARRAY || Z_TYPE_P(z) == IS_OBJECT) {
gc_zval_possible_root(Z_COUNTED_P(z) TSRMLS_CC);
}
}
static zend_always_inline void gc_remove_from_buffer(gc_root_buffer *root TSRMLS_DC)
{
root->next->prev = root->prev;
root->prev->next = root->next;
root->prev = GC_G(unused);
GC_G(unused) = root;
GC_BENCH_DEC(root_buf_length);
}
#define ALLOC_PERMANENT_ZVAL(z) \
do { \
(z) = (zval*)malloc(sizeof(zval_gc_info)); \
GC_ZVAL_INIT(z); \
} while (0)
/* The following macros override macros from zend_alloc.h */
#undef ALLOC_ZVAL
#define ALLOC_ZVAL(z) \
do { \
(z) = (zval*)emalloc(sizeof(zval_gc_info)); \
GC_ZVAL_INIT(z); \
} while (0)
#undef FREE_ZVAL
#define FREE_ZVAL(z) \
do { \
GC_REMOVE_ZVAL_FROM_BUFFER(z); \
efree(z); \
} while (0)
#undef ALLOC_ZVAL_REL
#define ALLOC_ZVAL_REL(z) \
do { \
(z) = (zval*)emalloc_rel(sizeof(zval_gc_info)); \
GC_ZVAL_INIT(z); \
} while (0)
#undef FREE_ZVAL_REL
#define FREE_ZVAL_REL(z) \
do { \
GC_REMOVE_ZVAL_FROM_BUFFER(z); \
efree_rel(z); \
} while (0)
#define FREE_ZVAL_EX(z) \
efree(z)
#define FREE_ZVAL_REL_EX(z) \
efree_rel(z)
#endif /* ZEND_GC_H */
/*

View file

@ -27,7 +27,7 @@
ZEND_API zend_class_entry *zend_ce_generator;
static zend_object_handlers zend_generator_handlers;
static zend_object_value zend_generator_create(zend_class_entry *class_type TSRMLS_DC);
static zend_object *zend_generator_create(zend_class_entry *class_type TSRMLS_DC);
static void zend_generator_cleanup_unfinished_execution(zend_generator *generator TSRMLS_DC) /* {{{ */
{
@ -35,7 +35,7 @@ static void zend_generator_cleanup_unfinished_execution(zend_generator *generato
zend_op_array *op_array = execute_data->op_array;
if (generator->send_target) {
Z_DELREF_PP(generator->send_target);
Z_DELREF_P(generator->send_target);
generator->send_target = NULL;
}
@ -60,14 +60,14 @@ static void zend_generator_cleanup_unfinished_execution(zend_generator *generato
switch (brk_opline->opcode) {
case ZEND_SWITCH_FREE:
{
temp_variable *var = EX_TMP_VAR(execute_data, brk_opline->op1.var);
zval_ptr_dtor(&var->var.ptr);
zval *var = EX_VAR_2(execute_data, brk_opline->op1.var);
zval_ptr_dtor(var);
}
break;
case ZEND_FREE:
{
temp_variable *var = EX_TMP_VAR(execute_data, brk_opline->op1.var);
zval_dtor(&var->tmp_var);
zval *var = EX_VAR_2(execute_data, brk_opline->op1.var);
zval_dtor(var);
}
break;
}
@ -77,20 +77,18 @@ static void zend_generator_cleanup_unfinished_execution(zend_generator *generato
/* Clear any backed up stack arguments */
{
void **ptr = generator->stack->top - 1;
void **end = zend_vm_stack_frame_base(execute_data);
zval *ptr = generator->stack->top - 1;
zval *end = zend_vm_stack_frame_base(execute_data);
for (; ptr >= end; --ptr) {
zval_ptr_dtor((zval **) ptr);
zval_ptr_dtor((zval*) ptr);
}
}
/* If yield was used as a function argument there may be active
* method calls those objects need to be freed */
while (execute_data->call >= execute_data->call_slots) {
if (execute_data->call->object) {
zval_ptr_dtor(&execute_data->call->object);
}
zval_ptr_dtor(&execute_data->call->object);
execute_data->call--;
}
}
@ -98,14 +96,14 @@ static void zend_generator_cleanup_unfinished_execution(zend_generator *generato
ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished_execution TSRMLS_DC) /* {{{ */
{
if (generator->value) {
if (Z_TYPE(generator->value) != IS_UNDEF) {
zval_ptr_dtor(&generator->value);
generator->value = NULL;
ZVAL_UNDEF(&generator->value);
}
if (generator->key) {
if (Z_TYPE(generator->key) != IS_UNDEF) {
zval_ptr_dtor(&generator->key);
generator->key = NULL;
ZVAL_UNDEF(&generator->key);
}
if (generator->execute_data) {
@ -118,9 +116,9 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
zend_clean_and_cache_symbol_table(execute_data->symbol_table TSRMLS_CC);
}
if (execute_data->current_this) {
zval_ptr_dtor(&execute_data->current_this);
}
//??? if (execute_data->current_this) {
//??? zval_ptr_dtor(&execute_data->current_this);
//??? }
/* A fatal error / die occurred during the generator execution. Trying to clean
* up the stack may not be safe in this case. */
@ -133,11 +131,11 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
* generator (for func_get_args) so those have to be freed too. */
{
zend_execute_data *prev_execute_data = execute_data->prev_execute_data;
void **arguments = prev_execute_data->function_state.arguments;
zval *arguments = prev_execute_data->function_state.arguments;
if (arguments) {
int arguments_count = (int) (zend_uintptr_t) *arguments;
zval **arguments_start = (zval **) (arguments - arguments_count);
int arguments_count = Z_LVAL_P(arguments);
zval *arguments_start = arguments - arguments_count;
int i;
for (i = 0; i < arguments_count; ++i) {
@ -164,8 +162,9 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
}
/* }}} */
static void zend_generator_dtor_storage(zend_generator *generator, zend_object_handle handle TSRMLS_DC) /* {{{ */
static void zend_generator_dtor_storage(zend_object *object TSRMLS_DC) /* {{{ */
{
zend_generator *generator = (zend_generator*) object;
zend_execute_data *ex = generator->execute_data;
zend_uint op_num, finally_op_num;
int i;
@ -203,8 +202,10 @@ static void zend_generator_dtor_storage(zend_generator *generator, zend_object_h
}
/* }}} */
static void zend_generator_free_storage(zend_generator *generator TSRMLS_DC) /* {{{ */
static void zend_generator_free_storage(zend_object *object TSRMLS_DC) /* {{{ */
{
zend_generator *generator = (zend_generator*) object;
zend_generator_close(generator, 0 TSRMLS_CC);
zend_object_std_dtor(&generator->std TSRMLS_CC);
@ -212,10 +213,9 @@ static void zend_generator_free_storage(zend_generator *generator TSRMLS_DC) /*
}
/* }}} */
static zend_object_value zend_generator_create(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
static zend_object *zend_generator_create(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
{
zend_generator *generator;
zend_object_value object;
generator = emalloc(sizeof(zend_generator));
memset(generator, 0, sizeof(zend_generator));
@ -224,33 +224,26 @@ static zend_object_value zend_generator_create(zend_class_entry *class_type TSRM
generator->largest_used_integer_key = -1;
zend_object_std_init(&generator->std, class_type TSRMLS_CC);
generator->std.handlers = &zend_generator_handlers;
object.handle = zend_objects_store_put(generator,
(zend_objects_store_dtor_t) zend_generator_dtor_storage,
(zend_objects_free_object_storage_t) zend_generator_free_storage,
NULL TSRMLS_CC
);
object.handlers = &zend_generator_handlers;
return object;
return (zend_object*)generator;
}
/* }}} */
static void copy_closure_static_var(zval **var TSRMLS_DC, int num_args, va_list args, zend_hash_key *key) /* {{{ */
static void copy_closure_static_var(zval *var TSRMLS_DC, int num_args, va_list args, zend_hash_key *key) /* {{{ */
{
HashTable *target = va_arg(args, HashTable *);
SEPARATE_ZVAL_TO_MAKE_IS_REF(var);
Z_ADDREF_PP(var);
zend_hash_quick_update(target, key->arKey, key->nKeyLength, key->h, var, sizeof(zval *), NULL);
Z_ADDREF_P(var);
zend_hash_update(target, key->key, var);
}
/* }}} */
/* Requires globals EG(scope), EG(current_scope), EG(This),
* EG(active_symbol_table) and EG(current_execute_data). */
ZEND_API zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC) /* {{{ */
ZEND_API void zend_generator_create_zval(zend_op_array *op_array, zval *return_value TSRMLS_DC) /* {{{ */
{
zval *return_value;
zend_generator *generator;
zend_execute_data *current_execute_data;
zend_op **opline_ptr;
@ -294,26 +287,23 @@ ZEND_API zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC) /*
EG(current_execute_data) = current_execute_data;
EG(opline_ptr) = opline_ptr;
ALLOC_INIT_ZVAL(return_value);
object_init_ex(return_value, zend_ce_generator);
if (EG(This)) {
Z_ADDREF_P(EG(This));
if (Z_TYPE(EG(This)) != IS_UNDEF) {
Z_ADDREF(EG(This));
}
/* Back up executor globals. */
execute_data->current_scope = EG(scope);
execute_data->current_called_scope = EG(called_scope);
//??? execute_data->current_scope = EG(scope);
//??? execute_data->current_called_scope = EG(called_scope);
execute_data->symbol_table = EG(active_symbol_table);
execute_data->current_this = EG(This);
//??? execute_data->current_this = EG(This);
/* Save execution context in generator object. */
generator = (zend_generator *) zend_object_store_get_object(return_value TSRMLS_CC);
generator = (zend_generator *) Z_OBJ_P(return_value);
generator->execute_data = execute_data;
generator->stack = EG(argument_stack);
EG(argument_stack) = current_stack;
return return_value;
}
/* }}} */
@ -341,28 +331,30 @@ ZEND_API void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{
{
/* Backup executor globals */
zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
//??? zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
zend_execute_data *original_execute_data = EG(current_execute_data);
zend_op **original_opline_ptr = EG(opline_ptr);
zend_op_array *original_active_op_array = EG(active_op_array);
HashTable *original_active_symbol_table = EG(active_symbol_table);
zval *original_This = EG(This);
zval original_This;
zend_class_entry *original_scope = EG(scope);
zend_class_entry *original_called_scope = EG(called_scope);
zend_vm_stack original_stack = EG(argument_stack);
ZVAL_COPY_VALUE(&original_This, &EG(This));
/* We (mis)use the return_value_ptr_ptr to provide the generator object
* to the executor, so YIELD will be able to set the yielded value */
EG(return_value_ptr_ptr) = (zval **) generator;
//??? EG(return_value_ptr_ptr) = (zval **) generator;
/* Set executor globals */
EG(current_execute_data) = generator->execute_data;
EG(opline_ptr) = &generator->execute_data->opline;
EG(active_op_array) = generator->execute_data->op_array;
EG(active_symbol_table) = generator->execute_data->symbol_table;
EG(This) = generator->execute_data->current_this;
EG(scope) = generator->execute_data->current_scope;
EG(called_scope) = generator->execute_data->current_called_scope;
//??? EG(This) = generator->execute_data->current_this;
//??? EG(scope) = generator->execute_data->current_scope;
//??? EG(called_scope) = generator->execute_data->current_called_scope;
EG(argument_stack) = generator->stack;
/* We want the backtrace to look as if the generator function was
@ -379,7 +371,7 @@ ZEND_API void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{
generator->flags &= ~ZEND_GENERATOR_CURRENTLY_RUNNING;
/* Restore executor globals */
EG(return_value_ptr_ptr) = original_return_value_ptr_ptr;
//??? EG(return_value_ptr_ptr) = original_return_value_ptr_ptr;
EG(current_execute_data) = original_execute_data;
EG(opline_ptr) = original_opline_ptr;
EG(active_op_array) = original_active_op_array;
@ -400,7 +392,7 @@ ZEND_API void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{
static void zend_generator_ensure_initialized(zend_generator *generator TSRMLS_DC) /* {{{ */
{
if (generator->execute_data && !generator->value) {
if (generator->execute_data && Z_TYPE(generator->value) == IS_UNDEF) {
zend_generator_resume(generator TSRMLS_CC);
generator->flags |= ZEND_GENERATOR_AT_FIRST_YIELD;
}
@ -427,7 +419,7 @@ ZEND_METHOD(Generator, rewind)
return;
}
generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
generator = (zend_generator *) Z_OBJ_P(getThis());
zend_generator_rewind(generator TSRMLS_CC);
}
@ -443,11 +435,11 @@ ZEND_METHOD(Generator, valid)
return;
}
generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
generator = (zend_generator *) Z_OBJ_P(getThis());
zend_generator_ensure_initialized(generator TSRMLS_CC);
RETURN_BOOL(generator->value != NULL);
RETURN_BOOL(Z_TYPE(generator->value) != IS_UNDEF);
}
/* }}} */
@ -461,12 +453,12 @@ ZEND_METHOD(Generator, current)
return;
}
generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
generator = (zend_generator *) Z_OBJ_P(getThis());
zend_generator_ensure_initialized(generator TSRMLS_CC);
if (generator->value) {
RETURN_ZVAL_FAST(generator->value);
if (Z_TYPE(generator->value) != IS_UNDEF) {
RETURN_ZVAL_FAST(&generator->value);
}
}
/* }}} */
@ -481,12 +473,12 @@ ZEND_METHOD(Generator, key)
return;
}
generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
generator = (zend_generator *) Z_OBJ_P(getThis());
zend_generator_ensure_initialized(generator TSRMLS_CC);
if (generator->key) {
RETURN_ZVAL_FAST(generator->key);
if (Z_TYPE(generator->key) != IS_UNDEF) {
RETURN_ZVAL_FAST(&generator->key);
}
}
/* }}} */
@ -501,7 +493,7 @@ ZEND_METHOD(Generator, next)
return;
}
generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
generator = (zend_generator *) Z_OBJ_P(getThis());
zend_generator_ensure_initialized(generator TSRMLS_CC);
@ -520,7 +512,7 @@ ZEND_METHOD(Generator, send)
return;
}
generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
generator = (zend_generator *) Z_OBJ_P(getThis());
zend_generator_ensure_initialized(generator TSRMLS_CC);
@ -531,15 +523,15 @@ ZEND_METHOD(Generator, send)
/* Put sent value in the target VAR slot, if it is used */
if (generator->send_target) {
Z_DELREF_PP(generator->send_target);
Z_DELREF_P(generator->send_target);
Z_ADDREF_P(value);
*generator->send_target = value;
ZVAL_COPY_VALUE(generator->send_target, value);
}
zend_generator_resume(generator TSRMLS_CC);
if (generator->value) {
RETURN_ZVAL_FAST(generator->value);
if (Z_TYPE(generator->value) != IS_UNDEF) {
RETURN_ZVAL_FAST(&generator->value);
}
}
/* }}} */
@ -548,17 +540,16 @@ ZEND_METHOD(Generator, send)
* Throws an exception into the generator */
ZEND_METHOD(Generator, throw)
{
zval *exception, *exception_copy;
zval *exception, exception_copy;
zend_generator *generator;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &exception) == FAILURE) {
return;
}
ALLOC_ZVAL(exception_copy);
MAKE_COPY_ZVAL(&exception, exception_copy);
ZVAL_COPY_VALUE(&exception_copy, exception);
generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
generator = (zend_generator *) Z_OBJ_P(getThis());
zend_generator_ensure_initialized(generator TSRMLS_CC);
@ -567,19 +558,19 @@ ZEND_METHOD(Generator, throw)
zend_execute_data *current_execute_data = EG(current_execute_data);
EG(current_execute_data) = generator->execute_data;
zend_throw_exception_object(exception_copy TSRMLS_CC);
zend_throw_exception_object(&exception_copy TSRMLS_CC);
EG(current_execute_data) = current_execute_data;
zend_generator_resume(generator TSRMLS_CC);
if (generator->value) {
RETURN_ZVAL_FAST(generator->value);
if (Z_TYPE(generator->value) != IS_UNDEF) {
RETURN_ZVAL_FAST(&generator->value);
}
} else {
/* If the generator is already closed throw the exception in the
* current context */
zend_throw_exception_object(exception_copy TSRMLS_CC);
zend_throw_exception_object(&exception_copy TSRMLS_CC);
}
}
/* }}} */
@ -606,7 +597,7 @@ static void zend_generator_iterator_dtor(zend_object_iterator *iterator TSRMLS_D
{
zval *object = ((zend_generator_iterator *) iterator)->object;
zval_ptr_dtor(&object);
zval_ptr_dtor(object);
}
/* }}} */
@ -616,21 +607,17 @@ static int zend_generator_iterator_valid(zend_object_iterator *iterator TSRMLS_D
zend_generator_ensure_initialized(generator TSRMLS_CC);
return generator->value != NULL ? SUCCESS : FAILURE;
return Z_TYPE(generator->value) != IS_UNDEF ? SUCCESS : FAILURE;
}
/* }}} */
static void zend_generator_iterator_get_data(zend_object_iterator *iterator, zval ***data TSRMLS_DC) /* {{{ */
static zval *zend_generator_iterator_get_data(zend_object_iterator *iterator TSRMLS_DC) /* {{{ */
{
zend_generator *generator = (zend_generator *) iterator->data;
zend_generator_ensure_initialized(generator TSRMLS_CC);
if (generator->value) {
*data = &generator->value;
} else {
*data = NULL;
}
return &generator->value;
}
/* }}} */
@ -640,8 +627,8 @@ static void zend_generator_iterator_get_key(zend_object_iterator *iterator, zval
zend_generator_ensure_initialized(generator TSRMLS_CC);
if (generator->key) {
ZVAL_ZVAL(key, generator->key, 1, 0);
if (Z_TYPE(generator->key) != IS_UNDEF) {
ZVAL_ZVAL(key, &generator->key, 1, 0);
} else {
ZVAL_NULL(key);
}
@ -680,7 +667,7 @@ zend_object_iterator *zend_generator_get_iterator(zend_class_entry *ce, zval *ob
zend_generator_iterator *iterator;
zend_generator *generator;
generator = (zend_generator *) zend_object_store_get_object(object TSRMLS_CC);
generator = (zend_generator *) Z_OBJ_P(object);
if (!generator->execute_data) {
zend_throw_exception(NULL, "Cannot traverse an already closed generator", 0 TSRMLS_CC);
@ -745,8 +732,10 @@ void zend_register_generator_ce(TSRMLS_D) /* {{{ */
zend_ce_generator->iterator_funcs.funcs = &zend_generator_iterator_functions;
memcpy(&zend_generator_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
zend_generator_handlers.get_constructor = zend_generator_get_constructor;
zend_generator_handlers.free_obj = zend_generator_free_storage;
zend_generator_handlers.dtor_obj = zend_generator_dtor_storage;
zend_generator_handlers.clone_obj = NULL;
zend_generator_handlers.get_constructor = zend_generator_get_constructor;
}
/* }}} */

View file

@ -45,11 +45,11 @@ typedef struct _zend_generator {
zend_vm_stack stack;
/* Current value */
zval *value;
zval value;
/* Current key */
zval *key;
zval key;
/* Variable to put sent value into */
zval **send_target;
zval *send_target;
/* Largest used integer key for auto-incrementing keys */
long largest_used_integer_key;
@ -62,7 +62,7 @@ static const zend_uchar ZEND_GENERATOR_FORCED_CLOSE = 0x2;
static const zend_uchar ZEND_GENERATOR_AT_FIRST_YIELD = 0x4;
void zend_register_generator_ce(TSRMLS_D);
ZEND_API zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC);
ZEND_API void zend_generator_create_zval(zend_op_array *op_array, zval *return_value TSRMLS_DC);
ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished_execution TSRMLS_DC);
ZEND_API void zend_generator_resume(zend_generator *generator TSRMLS_DC);

View file

@ -85,7 +85,7 @@ struct _zend_compiler_globals {
zend_stack function_call_stack;
char *compiled_filename;
zend_string *compiled_filename;
int zend_lineno;
@ -124,12 +124,11 @@ struct _zend_compiler_globals {
zend_uint access_type;
char *doc_comment;
zend_uint doc_comment_len;
zend_string *doc_comment;
zend_uint compiler_options; /* set of ZEND_COMPILE_* constants */
zval *current_namespace;
zval current_namespace;
HashTable *current_import;
HashTable *current_import_function;
HashTable *current_import_const;
@ -141,14 +140,7 @@ struct _zend_compiler_globals {
zend_compiler_context context;
zend_stack context_stack;
/* interned strings */
char *interned_strings_start;
char *interned_strings_end;
char *interned_strings_top;
char *interned_strings_snapshot_top;
#ifndef ZTS
char *interned_empty_string;
#endif
zend_string *empty_string;
HashTable interned_strings;
@ -166,13 +158,10 @@ struct _zend_compiler_globals {
struct _zend_executor_globals {
zval **return_value_ptr_ptr;
//??? zval **return_value_ptr_ptr;
zval uninitialized_zval;
zval *uninitialized_zval_ptr;
zval error_zval;
zval *error_zval_ptr;
/* symbol table cache */
HashTable *symtable_cache[SYMTABLE_CACHE_SIZE];
@ -182,7 +171,7 @@ struct _zend_executor_globals {
zend_op **opline_ptr;
HashTable *active_symbol_table;
HashTable symbol_table; /* main symbol table */
zend_array symbol_table; /* main symbol table */
HashTable included_files; /* files already included */
@ -201,7 +190,7 @@ struct _zend_executor_globals {
zend_class_entry *scope;
zend_class_entry *called_scope; /* Scope of the calling class */
zval *This;
zval This;
long precision;
@ -226,11 +215,11 @@ struct _zend_executor_globals {
zend_vm_stack argument_stack;
int user_error_handler_error_reporting;
zval *user_error_handler;
zval *user_exception_handler;
zval user_error_handler;
zval user_exception_handler;
zend_stack user_error_handlers_error_reporting;
zend_ptr_stack user_error_handlers;
zend_ptr_stack user_exception_handlers;
zend_stack user_error_handlers;
zend_stack user_exception_handlers;
zend_error_handling_t error_handling;
zend_class_entry *exception_class;
@ -245,7 +234,7 @@ struct _zend_executor_globals {
zend_ini_entry *error_reporting_ini_entry;
zend_objects_store objects_store;
zval *exception, *prev_exception;
zend_object *exception, *prev_exception;
zend_op *opline_before_exception;
zend_op exception_op[3];
@ -313,6 +302,9 @@ struct _zend_php_scanner_globals {
zend_encoding_filter input_filter;
zend_encoding_filter output_filter;
const zend_encoding *script_encoding;
/* initial string length after scanning to first variable */
int scanned_string_len;
};
#endif /* ZEND_GLOBALS_H */

File diff suppressed because it is too large Load diff

View file

@ -34,65 +34,32 @@
#define HASH_ADD (1<<1)
#define HASH_NEXT_INSERT (1<<2)
#define HASH_DEL_KEY 0
#define HASH_DEL_INDEX 1
#define HASH_DEL_KEY_QUICK 2
#define HASH_UPDATE_KEY_IF_NONE 0
#define HASH_UPDATE_KEY_IF_BEFORE 1
#define HASH_UPDATE_KEY_IF_AFTER 2
#define HASH_UPDATE_KEY_ANYWAY 3
typedef ulong (*hash_func_t)(const char *arKey, uint nKeyLength);
#define INVALID_IDX ((uint)-1)
#define HASH_FLAG_PERSISTENT (1<<0)
#define HASH_FLAG_APPLY_PROTECTION (1<<1)
#define HASH_FLAG_PACKED (1<<2)
#define HASH_MASK_CONSISTENCY 0x60
typedef int (*compare_func_t)(const void *, const void * TSRMLS_DC);
typedef void (*sort_func_t)(void *, size_t, register size_t, compare_func_t TSRMLS_DC);
typedef void (*dtor_func_t)(void *pDest);
typedef void (*copy_ctor_func_t)(void *pElement);
typedef void (*copy_ctor_param_func_t)(void *pElement, void *pParam);
struct _hashtable;
typedef struct bucket {
ulong h; /* Used for numeric indexing */
uint nKeyLength;
void *pData;
void *pDataPtr;
struct bucket *pListNext;
struct bucket *pListLast;
struct bucket *pNext;
struct bucket *pLast;
const char *arKey;
} Bucket;
typedef struct _hashtable {
uint nTableSize;
uint nTableMask;
uint nNumOfElements;
ulong nNextFreeElement;
Bucket *pInternalPointer; /* Used for element traversal */
Bucket *pListHead;
Bucket *pListTail;
Bucket **arBuckets;
dtor_func_t pDestructor;
zend_bool persistent;
unsigned char nApplyCount;
zend_bool bApplyProtection;
#if ZEND_DEBUG
int inconsistent;
#endif
} HashTable;
typedef void (*sort_func_t)(void *, size_t, size_t, compare_func_t TSRMLS_DC);
typedef void (*dtor_func_t)(zval *pDest);
typedef void (*copy_ctor_func_t)(zval *pElement);
typedef struct _zend_hash_key {
const char *arKey;
uint nKeyLength;
ulong h;
ulong h;
zend_string *key;
} zend_hash_key;
typedef zend_bool (*merge_checker_func_t)(HashTable *target_ht, zval *source_data, zend_hash_key *hash_key, void *pParam);
typedef zend_bool (*merge_checker_func_t)(HashTable *target_ht, void *source_data, zend_hash_key *hash_key, void *pParam);
typedef Bucket* HashPosition;
typedef uint HashPosition;
BEGIN_EXTERN_C()
@ -104,35 +71,38 @@ ZEND_API void zend_hash_clean(HashTable *ht);
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent) _zend_hash_init((ht), (nSize), (pDestructor), (persistent) ZEND_FILE_LINE_CC)
#define zend_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, bApplyProtection) _zend_hash_init_ex((ht), (nSize), (pDestructor), (persistent), (bApplyProtection) ZEND_FILE_LINE_CC)
ZEND_API void zend_hash_packed_to_hash(HashTable *ht);
ZEND_API void zend_hash_to_packed(HashTable *ht);
/* additions/updates/changes */
ZEND_API int _zend_hash_add_or_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
#define zend_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
_zend_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_hash_add(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
_zend_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
ZEND_API zval *_zend_hash_add_or_update(HashTable *ht, zend_string *key, zval *pData, int flag ZEND_FILE_LINE_DC);
#define zend_hash_update(ht, key, pData) \
_zend_hash_add_or_update(ht, key, pData, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_hash_add(ht, key, pData) \
_zend_hash_add_or_update(ht, key, pData, HASH_ADD ZEND_FILE_LINE_CC)
ZEND_API int _zend_hash_quick_add_or_update(HashTable *ht, const char *arKey, uint nKeyLength, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
#define zend_hash_quick_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest) \
_zend_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_hash_quick_add(ht, arKey, nKeyLength, h, pData, nDataSize, pDest) \
_zend_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
ZEND_API zval *_zend_hash_str_add_or_update(HashTable *ht, const char *key, int len, zval *pData, int flag ZEND_FILE_LINE_DC);
#define zend_hash_str_update(ht, key, len, pData) \
_zend_hash_str_add_or_update(ht, key, len, pData, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_hash_str_add(ht, key, len, pData) \
_zend_hash_str_add_or_update(ht, key, len, pData, HASH_ADD ZEND_FILE_LINE_CC)
ZEND_API int _zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
#define zend_hash_index_update(ht, h, pData, nDataSize, pDest) \
_zend_hash_index_update_or_next_insert(ht, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_hash_next_index_insert(ht, pData, nDataSize, pDest) \
_zend_hash_index_update_or_next_insert(ht, 0, pData, nDataSize, pDest, HASH_NEXT_INSERT ZEND_FILE_LINE_CC)
ZEND_API int zend_hash_add_empty_element(HashTable *ht, const char *arKey, uint nKeyLength);
ZEND_API zval *_zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, zval *pData, int flag ZEND_FILE_LINE_DC);
#define zend_hash_index_update(ht, h, pData) \
_zend_hash_index_update_or_next_insert(ht, h, pData, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_hash_next_index_insert(ht, pData) \
_zend_hash_index_update_or_next_insert(ht, 0, pData, HASH_NEXT_INSERT ZEND_FILE_LINE_CC)
ZEND_API zval *zend_hash_add_empty_element(HashTable *ht, zend_string *key);
ZEND_API zval *zend_hash_str_add_empty_element(HashTable *ht, const char *key, int len);
#define ZEND_HASH_APPLY_KEEP 0
#define ZEND_HASH_APPLY_REMOVE 1<<0
#define ZEND_HASH_APPLY_STOP 1<<1
typedef int (*apply_func_t)(void *pDest TSRMLS_DC);
typedef int (*apply_func_arg_t)(void *pDest, void *argument TSRMLS_DC);
typedef int (*apply_func_args_t)(void *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key);
typedef int (*apply_func_t)(zval *pDest TSRMLS_DC);
typedef int (*apply_func_arg_t)(zval *pDest, void *argument TSRMLS_DC);
typedef int (*apply_func_args_t)(zval *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key);
ZEND_API void zend_hash_graceful_destroy(HashTable *ht);
ZEND_API void zend_hash_graceful_reverse_destroy(HashTable *ht);
@ -150,24 +120,18 @@ ZEND_API void zend_hash_reverse_apply(HashTable *ht, apply_func_t apply_func TSR
/* Deletes */
ZEND_API int zend_hash_del_key_or_index(HashTable *ht, const char *arKey, uint nKeyLength, ulong h, int flag);
#define zend_hash_del(ht, arKey, nKeyLength) \
zend_hash_del_key_or_index(ht, arKey, nKeyLength, 0, HASH_DEL_KEY)
#define zend_hash_quick_del(ht, arKey, nKeyLength, h) \
zend_hash_del_key_or_index(ht, arKey, nKeyLength, h, HASH_DEL_KEY_QUICK)
#define zend_hash_index_del(ht, h) \
zend_hash_del_key_or_index(ht, NULL, 0, h, HASH_DEL_INDEX)
#define zend_get_hash_value \
zend_hash_func
ZEND_API int zend_hash_del(HashTable *ht, zend_string *key);
ZEND_API int zend_hash_str_del(HashTable *ht, const char *key, int len);
ZEND_API int zend_hash_index_del(HashTable *ht, ulong h);
/* Data retreival */
ZEND_API int zend_hash_find(const HashTable *ht, const char *arKey, uint nKeyLength, void **pData);
ZEND_API int zend_hash_quick_find(const HashTable *ht, const char *arKey, uint nKeyLength, ulong h, void **pData);
ZEND_API int zend_hash_index_find(const HashTable *ht, ulong h, void **pData);
ZEND_API zval *zend_hash_find(const HashTable *ht, zend_string *key);
ZEND_API zval *zend_hash_str_find(const HashTable *ht, const char *key, int len);
ZEND_API zval *zend_hash_index_find(const HashTable *ht, ulong h);
/* Misc */
ZEND_API int zend_hash_exists(const HashTable *ht, const char *arKey, uint nKeyLength);
ZEND_API int zend_hash_quick_exists(const HashTable *ht, const char *arKey, uint nKeyLength, ulong h);
ZEND_API int zend_hash_exists(const HashTable *ht, zend_string *key);
ZEND_API int zend_hash_str_exists(const HashTable *ht, const char *str, int len);
ZEND_API int zend_hash_index_exists(const HashTable *ht, ulong h);
ZEND_API ulong zend_hash_next_free_element(const HashTable *ht);
@ -176,16 +140,17 @@ ZEND_API ulong zend_hash_next_free_element(const HashTable *ht);
(zend_hash_get_current_key_type_ex(ht, pos) == HASH_KEY_NON_EXISTENT ? FAILURE : SUCCESS)
ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos);
ZEND_API int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos);
ZEND_API int zend_hash_get_current_key_ex(const HashTable *ht, char **str_index, uint *str_length, ulong *num_index, zend_bool duplicate, HashPosition *pos);
ZEND_API int zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, ulong *num_index, zend_bool duplicate, HashPosition *pos);
ZEND_API void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos);
ZEND_API int zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos);
ZEND_API int zend_hash_get_current_data_ex(HashTable *ht, void **pData, HashPosition *pos);
ZEND_API zval *zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos);
ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos);
ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos);
ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const char *str_index, uint str_length, ulong num_index, int mode, HashPosition *pos);
ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, zend_string *str_index, ulong num_index, int mode, HashPosition *pos);
typedef struct _HashPointer {
HashPosition pos;
HashTable *ht;
ulong h;
} HashPointer;
@ -204,8 +169,8 @@ ZEND_API int zend_hash_set_pointer(HashTable *ht, const HashPointer *ptr);
zend_hash_get_current_key_zval_ex(ht, key, NULL)
#define zend_hash_get_current_key_type(ht) \
zend_hash_get_current_key_type_ex(ht, NULL)
#define zend_hash_get_current_data(ht, pData) \
zend_hash_get_current_data_ex(ht, pData, NULL)
#define zend_hash_get_current_data(ht) \
zend_hash_get_current_data_ex(ht, NULL)
#define zend_hash_internal_pointer_reset(ht) \
zend_hash_internal_pointer_reset_ex(ht, NULL)
#define zend_hash_internal_pointer_end(ht) \
@ -214,85 +179,20 @@ ZEND_API int zend_hash_set_pointer(HashTable *ht, const HashPointer *ptr);
zend_hash_update_current_key_ex(ht, key_type, str_index, str_length, num_index, HASH_UPDATE_KEY_ANYWAY, NULL)
/* Copying, merging and sorting */
ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size);
ZEND_API void _zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, int overwrite ZEND_FILE_LINE_DC);
ZEND_API void zend_hash_merge_ex(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, uint size, merge_checker_func_t pMergeSource, void *pParam);
ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor);
ZEND_API void _zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, int overwrite ZEND_FILE_LINE_DC);
ZEND_API void zend_hash_merge_ex(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, merge_checker_func_t pMergeSource, void *pParam);
ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func, compare_func_t compare_func, int renumber TSRMLS_DC);
ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar, zend_bool ordered TSRMLS_DC);
ZEND_API int zend_hash_minmax(const HashTable *ht, compare_func_t compar, int flag, void **pData TSRMLS_DC);
ZEND_API zval *zend_hash_minmax(const HashTable *ht, compare_func_t compar, int flag TSRMLS_DC);
#define zend_hash_merge(target, source, pCopyConstructor, tmp, size, overwrite) \
_zend_hash_merge(target, source, pCopyConstructor, tmp, size, overwrite ZEND_FILE_LINE_CC)
#define zend_hash_merge(target, source, pCopyConstructor, overwrite) \
_zend_hash_merge(target, source, pCopyConstructor, overwrite ZEND_FILE_LINE_CC)
ZEND_API int zend_hash_num_elements(const HashTable *ht);
ZEND_API int zend_hash_rehash(HashTable *ht);
/*
* DJBX33A (Daniel J. Bernstein, Times 33 with Addition)
*
* This is Daniel J. Bernstein's popular `times 33' hash function as
* posted by him years ago on comp.lang.c. It basically uses a function
* like ``hash(i) = hash(i-1) * 33 + str[i]''. This is one of the best
* known hash functions for strings. Because it is both computed very
* fast and distributes very well.
*
* The magic of number 33, i.e. why it works better than many other
* constants, prime or not, has never been adequately explained by
* anyone. So I try an explanation: if one experimentally tests all
* multipliers between 1 and 256 (as RSE did now) one detects that even
* numbers are not useable at all. The remaining 128 odd numbers
* (except for the number 1) work more or less all equally well. They
* all distribute in an acceptable way and this way fill a hash table
* with an average percent of approx. 86%.
*
* If one compares the Chi^2 values of the variants, the number 33 not
* even has the best value. But the number 33 and a few other equally
* good numbers like 17, 31, 63, 127 and 129 have nevertheless a great
* advantage to the remaining numbers in the large set of possible
* multipliers: their multiply operation can be replaced by a faster
* operation based on just one shift plus either a single addition
* or subtraction operation. And because a hash function has to both
* distribute good _and_ has to be very fast to compute, those few
* numbers should be preferred and seems to be the reason why Daniel J.
* Bernstein also preferred it.
*
*
* -- Ralf S. Engelschall <rse@engelschall.com>
*/
static inline ulong zend_inline_hash_func(const char *arKey, uint nKeyLength)
{
register ulong hash = 5381;
/* variant with the hash unrolled eight times */
for (; nKeyLength >= 8; nKeyLength -= 8) {
hash = ((hash << 5) + hash) + *arKey++;
hash = ((hash << 5) + hash) + *arKey++;
hash = ((hash << 5) + hash) + *arKey++;
hash = ((hash << 5) + hash) + *arKey++;
hash = ((hash << 5) + hash) + *arKey++;
hash = ((hash << 5) + hash) + *arKey++;
hash = ((hash << 5) + hash) + *arKey++;
hash = ((hash << 5) + hash) + *arKey++;
}
switch (nKeyLength) {
case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
case 3: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
case 2: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */
case 1: hash = ((hash << 5) + hash) + *arKey++; break;
case 0: break;
EMPTY_SWITCH_DEFAULT_CASE()
}
return hash;
}
ZEND_API ulong zend_hash_func(const char *arKey, uint nKeyLength);
#if ZEND_DEBUG
/* debug */
void zend_hash_display_pListTail(const HashTable *ht);
@ -348,42 +248,211 @@ END_EXTERN_C()
ZEND_HANDLE_NUMERIC_EX(key, length, idx, return func); \
} while (0)
static inline int zend_symtable_update(HashTable *ht, const char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest) \
static inline zval *zend_symtable_update(HashTable *ht, zend_string *key, zval *pData)
{
ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_update(ht, idx, pData, nDataSize, pDest));
return zend_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest);
ZEND_HANDLE_NUMERIC(key->val, key->len+1, zend_hash_index_update(ht, idx, pData));
return zend_hash_update(ht, key, pData);
}
static inline int zend_symtable_del(HashTable *ht, const char *arKey, uint nKeyLength)
static inline int zend_symtable_del(HashTable *ht, zend_string *key)
{
ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_del(ht, idx));
return zend_hash_del(ht, arKey, nKeyLength);
ZEND_HANDLE_NUMERIC(key->val, key->len+1, zend_hash_index_del(ht, idx));
return zend_hash_del(ht, key);
}
static inline int zend_symtable_find(HashTable *ht, const char *arKey, uint nKeyLength, void **pData)
static inline zval *zend_symtable_find(HashTable *ht, zend_string *key)
{
ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_find(ht, idx, pData));
return zend_hash_find(ht, arKey, nKeyLength, pData);
ZEND_HANDLE_NUMERIC(key->val, key->len+1, zend_hash_index_find(ht, idx));
return zend_hash_find(ht, key);
}
static inline int zend_symtable_exists(HashTable *ht, const char *arKey, uint nKeyLength)
static inline int zend_symtable_exists(HashTable *ht, zend_string *key)
{
ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_exists(ht, idx));
return zend_hash_exists(ht, arKey, nKeyLength);
ZEND_HANDLE_NUMERIC(key->val, key->len+1, zend_hash_index_exists(ht, idx));
return zend_hash_exists(ht, key);
}
static inline int zend_symtable_update_current_key_ex(HashTable *ht, const char *arKey, uint nKeyLength, int mode, HashPosition *pos)
static inline zval *zend_symtable_str_update(HashTable *ht, const char *str, int len, zval *pData)
{
ZEND_HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_update_current_key_ex(ht, HASH_KEY_IS_LONG, NULL, 0, idx, mode, pos));
return zend_hash_update_current_key_ex(ht, HASH_KEY_IS_STRING, arKey, nKeyLength, 0, mode, pos);
ZEND_HANDLE_NUMERIC(str, len+1, zend_hash_index_update(ht, idx, pData));
return zend_hash_str_update(ht, str, len, pData);
}
#define zend_symtable_update_current_key(ht,arKey,nKeyLength,mode) \
zend_symtable_update_current_key_ex(ht, arKey, nKeyLength, mode, NULL)
static inline int zend_symtable_str_del(HashTable *ht, const char *str, int len)
{
ZEND_HANDLE_NUMERIC(str, len+1, zend_hash_index_del(ht, idx));
return zend_hash_str_del(ht, str, len);
}
static inline zval *zend_symtable_str_find(HashTable *ht, const char *str, int len)
{
ZEND_HANDLE_NUMERIC(str, len+1, zend_hash_index_find(ht, idx));
return zend_hash_str_find(ht, str, len);
}
static inline int zend_symtable_str_exists(HashTable *ht, const char *str, int len)
{
ZEND_HANDLE_NUMERIC(str, len+1, zend_hash_index_exists(ht, idx));
return zend_hash_str_exists(ht, str, len);
}
static inline int zend_symtable_update_current_key_ex(HashTable *ht, zend_string *key, int mode, HashPosition *pos)
{
ZEND_HANDLE_NUMERIC(key->val, key->len+1, zend_hash_update_current_key_ex(ht, HASH_KEY_IS_LONG, NULL, idx, mode, pos));
return zend_hash_update_current_key_ex(ht, HASH_KEY_IS_STRING, key, 0, mode, pos);
}
#define zend_symtable_update_current_key(ht, key, mode) \
zend_symtable_update_current_key_ex(ht, key, mode, NULL)
static inline void *zend_hash_add_ptr(HashTable *ht, zend_string *key, void *pData)
{
zval tmp, *zv;
ZVAL_PTR(&tmp, pData);
zv = zend_hash_add(ht, key, &tmp);
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_str_add_ptr(HashTable *ht, const char *str, int len, void *pData)
{
zval tmp, *zv;
ZVAL_PTR(&tmp, pData);
zv = zend_hash_str_add(ht, str, len, &tmp);
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_update_ptr(HashTable *ht, zend_string *key, void *pData)
{
zval tmp, *zv;
ZVAL_PTR(&tmp, pData);
zv = zend_hash_update(ht, key, &tmp);
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_str_update_ptr(HashTable *ht, const char *str, int len, void *pData)
{
zval tmp, *zv;
ZVAL_PTR(&tmp, pData);
zv = zend_hash_str_update(ht, str, len, &tmp);
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_add_mem(HashTable *ht, zend_string *key, void *pData, size_t size)
{
void *p;
p = pemalloc(size, ht->flags & HASH_FLAG_PERSISTENT);
memcpy(p, pData, size);
return zend_hash_add_ptr(ht, key, p);
}
static inline void *zend_hash_str_add_mem(HashTable *ht, const char *str, int len, void *pData, size_t size)
{
void *p;
p = pemalloc(size, ht->flags & HASH_FLAG_PERSISTENT);
memcpy(p, pData, size);
return zend_hash_str_add_ptr(ht, str, len, p);
}
static inline void *zend_hash_update_mem(HashTable *ht, zend_string *key, void *pData, size_t size)
{
void *p;
p = pemalloc(size, ht->flags & HASH_FLAG_PERSISTENT);
memcpy(p, pData, size);
return zend_hash_update_ptr(ht, key, p);
}
static inline void *zend_hash_str_update_mem(HashTable *ht, const char *str, int len, void *pData, size_t size)
{
void *p;
p = pemalloc(size, ht->flags & HASH_FLAG_PERSISTENT);
memcpy(p, pData, size);
return zend_hash_str_update_ptr(ht, str, len, p);
}
static inline void *zend_hash_index_update_ptr(HashTable *ht, ulong h, void *pData)
{
zval tmp, *zv;
ZVAL_PTR(&tmp, pData);
zv = zend_hash_index_update(ht, h, &tmp);
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_next_index_insert_ptr(HashTable *ht, void *pData)
{
zval tmp, *zv;
ZVAL_PTR(&tmp, pData);
zv = zend_hash_next_index_insert(ht, &tmp);
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_index_update_mem(HashTable *ht, ulong h, void *pData, size_t size)
{
void *p;
p = pemalloc(size, ht->flags & HASH_FLAG_PERSISTENT);
memcpy(p, pData, size);
return zend_hash_index_update_ptr(ht, h, p);
}
static inline void *zend_hash_next_index_insert_mem(HashTable *ht, void *pData, size_t size)
{
void *p;
p = pemalloc(size, ht->flags & HASH_FLAG_PERSISTENT);
memcpy(p, pData, size);
return zend_hash_next_index_insert_ptr(ht, p);
}
static inline void *zend_hash_find_ptr(HashTable *ht, zend_string *key)
{
zval *zv;
zv = zend_hash_find(ht, key);
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_str_find_ptr(HashTable *ht, const char *str, int len)
{
zval *zv;
zv = zend_hash_str_find(ht, str, len);
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_index_find_ptr(HashTable *ht, ulong h)
{
zval *zv;
zv = zend_hash_index_find(ht, h);
return zv ? Z_PTR_P(zv) : NULL;
}
static inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht, HashPosition *pos)
{
zval *zv;
zv = zend_hash_get_current_data_ptr_ex(ht, pos);
return zv ? Z_PTR_P(zv) : NULL;
}
#define zend_hash_get_current_data_ptr(ht) \
zend_hash_get_current_data_ptr_ex(ht, NULL)
#endif /* ZEND_HASH_H */
/*

View file

@ -150,7 +150,7 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
case T_DOC_COMMENT:
break;
default:
efree(token.value.str.val);
STR_RELEASE(Z_STR(token));
break;
}
}
@ -211,7 +211,7 @@ ZEND_API void zend_strip(TSRMLS_D)
break;
default:
efree(token.value.str.val);
STR_RELEASE(Z_STR(token));
break;
}
}

View file

@ -138,7 +138,7 @@ dflt_printout:
case T_WHITESPACE:
break;
default:
efree(token.value.str.val);
STR_RELEASE(Z_STR(token));
break;
}
}

View file

@ -150,17 +150,17 @@ static int ini_key_compare(const void *a, const void *b TSRMLS_DC) /* {{{ */
const Bucket *f;
const Bucket *s;
f = *((const Bucket **) a);
s = *((const Bucket **) b);
f = (const Bucket *) a;
s = (const Bucket *) b;
if (f->nKeyLength == 0 && s->nKeyLength == 0) { /* both numeric */
return ZEND_NORMALIZE_BOOL(f->nKeyLength - s->nKeyLength);
} else if (f->nKeyLength == 0) { /* f is numeric, s is not */
if (!f->key && !s->key) { /* both numeric */
return ZEND_NORMALIZE_BOOL(f->h - s->h);
} else if (!f->key) { /* f is numeric, s is not */
return -1;
} else if (s->nKeyLength == 0) { /* s is numeric, f is not */
} else if (!s->key) { /* s is numeric, f is not */
return 1;
} else { /* both strings */
return zend_binary_strcasecmp(f->arKey, f->nKeyLength, s->arKey, s->nKeyLength);
return zend_binary_strcasecmp(f->key->val, f->key->len, s->key->val, s->key->len);
}
}
/* }}} */
@ -198,7 +198,7 @@ ZEND_API int zend_register_ini_entries(const zend_ini_entry *ini_entry, int modu
while (p->name) {
config_directive_success = 0;
if (zend_hash_add(directives, p->name, p->name_length, (void*)p, sizeof(zend_ini_entry), (void **) &hashed_ini_entry) == FAILURE) {
if ((hashed_ini_entry = zend_hash_str_add_mem(directives, p->name, p->name_length, (void*)p, sizeof(zend_ini_entry))) == NULL) {
zend_unregister_ini_entries(module_number TSRMLS_CC);
return FAILURE;
}
@ -244,22 +244,22 @@ ZEND_API void zend_ini_refresh_caches(int stage TSRMLS_DC) /* {{{ */
/* }}} */
#endif
ZEND_API int zend_alter_ini_entry(char *name, uint name_length, char *new_value, uint new_value_length, int modify_type, int stage) /* {{{ */
ZEND_API int zend_alter_ini_entry(zend_string *name, char *new_value, uint new_value_length, int modify_type, int stage) /* {{{ */
{
TSRMLS_FETCH();
return zend_alter_ini_entry_ex(name, name_length, new_value, new_value_length, modify_type, stage, 0 TSRMLS_CC);
return zend_alter_ini_entry_ex(name, new_value, new_value_length, modify_type, stage, 0 TSRMLS_CC);
}
/* }}} */
ZEND_API int zend_alter_ini_entry_ex(char *name, uint name_length, char *new_value, uint new_value_length, int modify_type, int stage, int force_change TSRMLS_DC) /* {{{ */
ZEND_API int zend_alter_ini_entry_ex(zend_string *name, char *new_value, uint new_value_length, int modify_type, int stage, int force_change TSRMLS_DC) /* {{{ */
{
zend_ini_entry *ini_entry;
char *duplicate;
zend_bool modifiable;
zend_bool modified;
if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == FAILURE) {
if ((ini_entry = zend_hash_find_ptr(EG(ini_directives), name)) == NULL) {
return FAILURE;
}
@ -285,7 +285,7 @@ ZEND_API int zend_alter_ini_entry_ex(char *name, uint name_length, char *new_val
ini_entry->orig_value_length = ini_entry->value_length;
ini_entry->orig_modifiable = modifiable;
ini_entry->modified = 1;
zend_hash_add(EG(modified_ini_directives), name, name_length, &ini_entry, sizeof(zend_ini_entry*), NULL);
zend_hash_add_ptr(EG(modified_ini_directives), name, ini_entry);
}
duplicate = estrndup(new_value, new_value_length);
@ -306,19 +306,19 @@ ZEND_API int zend_alter_ini_entry_ex(char *name, uint name_length, char *new_val
}
/* }}} */
ZEND_API int zend_restore_ini_entry(char *name, uint name_length, int stage) /* {{{ */
ZEND_API int zend_restore_ini_entry(zend_string *name, int stage) /* {{{ */
{
zend_ini_entry *ini_entry;
TSRMLS_FETCH();
if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == FAILURE ||
if ((ini_entry = zend_hash_find_ptr(EG(ini_directives), name)) == NULL ||
(stage == ZEND_INI_STAGE_RUNTIME && (ini_entry->modifiable & ZEND_INI_USER) == 0)) {
return FAILURE;
}
if (EG(modified_ini_directives)) {
if (zend_restore_ini_entry_cb(ini_entry, stage TSRMLS_CC) == 0) {
zend_hash_del(EG(modified_ini_directives), name, name_length);
zend_hash_del(EG(modified_ini_directives), name);
} else {
return FAILURE;
}
@ -332,7 +332,8 @@ ZEND_API int zend_ini_register_displayer(char *name, uint name_length, void (*di
{
zend_ini_entry *ini_entry;
if (zend_hash_find(registered_zend_ini_directives, name, name_length, (void **) &ini_entry) == FAILURE) {
ini_entry = zend_hash_str_find_ptr(registered_zend_ini_directives, name, name_length);
if (ini_entry == NULL) {
return FAILURE;
}
@ -350,7 +351,8 @@ ZEND_API long zend_ini_long(char *name, uint name_length, int orig) /* {{{ */
zend_ini_entry *ini_entry;
TSRMLS_FETCH();
if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == SUCCESS) {
ini_entry = zend_hash_str_find_ptr(EG(ini_directives), name, name_length);
if (ini_entry) {
if (orig && ini_entry->modified) {
return (ini_entry->orig_value ? strtol(ini_entry->orig_value, NULL, 0) : 0);
} else {
@ -367,7 +369,8 @@ ZEND_API double zend_ini_double(char *name, uint name_length, int orig) /* {{{ *
zend_ini_entry *ini_entry;
TSRMLS_FETCH();
if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == SUCCESS) {
ini_entry = zend_hash_str_find_ptr(EG(ini_directives), name, name_length);
if (ini_entry) {
if (orig && ini_entry->modified) {
return (double) (ini_entry->orig_value ? zend_strtod(ini_entry->orig_value, NULL) : 0.0);
} else {
@ -384,7 +387,8 @@ ZEND_API char *zend_ini_string_ex(char *name, uint name_length, int orig, zend_b
zend_ini_entry *ini_entry;
TSRMLS_FETCH();
if (zend_hash_find(EG(ini_directives), name, name_length, (void **) &ini_entry) == SUCCESS) {
ini_entry = zend_hash_str_find_ptr(EG(ini_directives), name, name_length);
if (ini_entry) {
if (exists) {
*exists = 1;
}

View file

@ -94,9 +94,9 @@ ZEND_API void zend_ini_sort_entries(TSRMLS_D);
ZEND_API int zend_register_ini_entries(const zend_ini_entry *ini_entry, int module_number TSRMLS_DC);
ZEND_API void zend_unregister_ini_entries(int module_number TSRMLS_DC);
ZEND_API void zend_ini_refresh_caches(int stage TSRMLS_DC);
ZEND_API int zend_alter_ini_entry(char *name, uint name_length, char *new_value, uint new_value_length, int modify_type, int stage);
ZEND_API int zend_alter_ini_entry_ex(char *name, uint name_length, char *new_value, uint new_value_length, int modify_type, int stage, int force_change TSRMLS_DC);
ZEND_API int zend_restore_ini_entry(char *name, uint name_length, int stage);
ZEND_API int zend_alter_ini_entry(zend_string *name, char *new_value, uint new_value_length, int modify_type, int stage);
ZEND_API int zend_alter_ini_entry_ex(zend_string *name, char *new_value, uint new_value_length, int modify_type, int stage, int force_change TSRMLS_DC);
ZEND_API int zend_restore_ini_entry(zend_string *name, int stage);
ZEND_API void display_ini_entries(zend_module_entry *module);
ZEND_API long zend_ini_long(char *name, uint name_length, int orig);

View file

@ -49,6 +49,7 @@ static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
{
int i_result;
int i_op1, i_op2;
int str_len;
char str_result[MAX_LENGTH_OF_LONG];
i_op1 = atoi(Z_STRVAL_P(op1));
@ -81,11 +82,8 @@ static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
break;
}
Z_STRLEN_P(result) = zend_sprintf(str_result, "%d", i_result);
Z_STRVAL_P(result) = (char *) malloc(Z_STRLEN_P(result)+1);
memcpy(Z_STRVAL_P(result), str_result, Z_STRLEN_P(result));
Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
Z_TYPE_P(result) = IS_STRING;
str_len = zend_sprintf(str_result, "%d", i_result);
ZVAL_PSTRINGL(result, str_result, str_len);
}
/* }}} */
@ -93,10 +91,7 @@ static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
*/
static void zend_ini_init_string(zval *result)
{
Z_STRVAL_P(result) = malloc(1);
Z_STRVAL_P(result)[0] = 0;
Z_STRLEN_P(result) = 0;
Z_TYPE_P(result) = IS_STRING;
ZVAL_EMPTY_PSTRING(result);
}
/* }}} */
@ -106,11 +101,10 @@ static void zend_ini_add_string(zval *result, zval *op1, zval *op2)
{
int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
Z_STRVAL_P(result) = (char *) realloc(Z_STRVAL_P(op1), length+1);
ZVAL_STR(result, STR_ALLOC(length, 1));
memcpy(Z_STRVAL_P(result), Z_STRVAL_P(op1), Z_STRLEN_P(op1));
memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
Z_STRVAL_P(result)[length] = 0;
Z_STRLEN_P(result) = length;
Z_TYPE_P(result) = IS_STRING;
}
/* }}} */
@ -125,9 +119,7 @@ static void zend_ini_get_constant(zval *result, zval *name TSRMLS_DC)
&& zend_get_constant(Z_STRVAL_P(name), Z_STRLEN_P(name), &z_constant TSRMLS_CC)) {
/* z_constant is emalloc()'d */
convert_to_string(&z_constant);
Z_STRVAL_P(result) = zend_strndup(Z_STRVAL(z_constant), Z_STRLEN(z_constant));
Z_STRLEN_P(result) = Z_STRLEN(z_constant);
Z_TYPE_P(result) = Z_TYPE(z_constant);
ZVAL_PSTRINGL(result, Z_STRVAL(z_constant), Z_STRLEN(z_constant));
zval_dtor(&z_constant);
free(Z_STRVAL_P(name));
} else {
@ -145,13 +137,11 @@ static void zend_ini_get_var(zval *result, zval *name TSRMLS_DC)
/* Fetch configuration option value */
if (zend_get_configuration_directive(Z_STRVAL_P(name), Z_STRLEN_P(name)+1, &curval) == SUCCESS) {
Z_STRVAL_P(result) = zend_strndup(Z_STRVAL(curval), Z_STRLEN(curval));
Z_STRLEN_P(result) = Z_STRLEN(curval);
ZVAL_PSTRINGL(result, Z_STRVAL(curval), Z_STRLEN(curval));
/* ..or if not found, try ENV */
} else if ((envvar = zend_getenv(Z_STRVAL_P(name), Z_STRLEN_P(name) TSRMLS_CC)) != NULL ||
(envvar = getenv(Z_STRVAL_P(name))) != NULL) {
Z_STRVAL_P(result) = strdup(envvar);
Z_STRLEN_P(result) = strlen(envvar);
ZVAL_PSTRING(result, envvar);
} else {
zend_ini_init_string(result);
}
@ -160,7 +150,7 @@ static void zend_ini_get_var(zval *result, zval *name TSRMLS_DC)
/* {{{ ini_error()
*/
static void ini_error(char *msg)
static void ini_error(const char *msg)
{
char *error_buf;
int error_buf_len;

File diff suppressed because it is too large Load diff

View file

@ -131,11 +131,9 @@ ZEND_API zend_ini_scanner_globals ini_scanner_globals;
/* Eat trailing whitespace */
#define EAT_TRAILING_WHITESPACE() EAT_TRAILING_WHITESPACE_EX('X')
#define zend_ini_copy_value(retval, str, len) { \
Z_STRVAL_P(retval) = zend_strndup(str, len); \
Z_STRLEN_P(retval) = len; \
Z_TYPE_P(retval) = IS_STRING; \
}
#define zend_ini_copy_value(retval, str, len) \
ZVAL_STR(retval, STR_INIT(str, len, 1))
#define RETURN_TOKEN(type, str, len) { \
zend_ini_copy_value(ini_lval, str, len); \

View file

@ -1,13 +1,13 @@
/* Generated by re2c 0.13.5 */
#line 3 "Zend/zend_ini_scanner_defs.h"
enum YYCONDTYPE {
yycINITIAL,
yycST_OFFSET,
yycST_SECTION_VALUE,
yycST_VALUE,
yycST_SECTION_RAW,
yycST_DOUBLE_QUOTES,
yycST_VARNAME,
yycST_RAW,
};
/* Generated by re2c 0.13.5 */
#line 3 "Zend/zend_ini_scanner_defs.h"
enum YYCONDTYPE {
yycINITIAL,
yycST_OFFSET,
yycST_SECTION_VALUE,
yycST_VALUE,
yycST_SECTION_RAW,
yycST_DOUBLE_QUOTES,
yycST_VARNAME,
yycST_RAW,
};

View file

@ -31,24 +31,23 @@ ZEND_API zend_class_entry *zend_ce_serializable;
/* {{{ zend_call_method
Only returns the returned zval if retval_ptr != NULL */
ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, const char *function_name, int function_name_len, zval **retval_ptr_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC)
ZEND_API zval* zend_call_method(zval *object, zend_class_entry *obj_ce, zend_function **fn_proxy, const char *function_name, int function_name_len, zval *retval_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC)
{
int result;
zend_fcall_info fci;
zval z_fname;
zval *retval;
zval retval;
HashTable *function_table;
zval **params[2];
zval params[2];
params[0] = &arg1;
params[1] = &arg2;
ZVAL_COPY_VALUE(&params[0], arg1);
ZVAL_COPY_VALUE(&params[1], arg2);
fci.size = sizeof(fci);
/*fci.function_table = NULL; will be read form zend_class_entry of object if needed */
fci.object_ptr = object_pp ? *object_pp : NULL;
fci.function_name = &z_fname;
fci.retval_ptr_ptr = retval_ptr_ptr ? retval_ptr_ptr : &retval;
fci.object_ptr = object;
ZVAL_STRINGL(&fci.function_name, function_name, function_name_len);
fci.retval = retval_ptr ? retval_ptr : &retval;
fci.param_count = param_count;
fci.params = params;
fci.no_separation = 1;
@ -57,15 +56,14 @@ ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend
if (!fn_proxy && !obj_ce) {
/* no interest in caching and no information already present that is
* needed later inside zend_call_function. */
ZVAL_STRINGL(&z_fname, function_name, function_name_len, 0);
fci.function_table = !object_pp ? EG(function_table) : NULL;
fci.function_table = !object ? EG(function_table) : NULL;
result = zend_call_function(&fci, NULL TSRMLS_CC);
} else {
zend_fcall_info_cache fcic;
fcic.initialized = 1;
if (!obj_ce) {
obj_ce = object_pp ? Z_OBJCE_PP(object_pp) : NULL;
obj_ce = object ? Z_OBJCE_P(object) : NULL;
}
if (obj_ce) {
function_table = &obj_ce->function_table;
@ -73,9 +71,9 @@ ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend
function_table = EG(function_table);
}
if (!fn_proxy || !*fn_proxy) {
if (zend_hash_find(function_table, function_name, function_name_len+1, (void **) &fcic.function_handler) == FAILURE) {
if ((fcic.function_handler = zend_hash_find_ptr(function_table, Z_STR(fci.function_name))) == NULL) {
/* error at c-level */
zend_error(E_CORE_ERROR, "Couldn't find implementation for method %s%s%s", obj_ce ? obj_ce->name : "", obj_ce ? "::" : "", function_name);
zend_error(E_CORE_ERROR, "Couldn't find implementation for method %s%s%s", obj_ce ? obj_ce->name->val : "", obj_ce ? "::" : "", function_name);
}
if (fn_proxy) {
*fn_proxy = fcic.function_handler;
@ -84,8 +82,8 @@ ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend
fcic.function_handler = *fn_proxy;
}
fcic.calling_scope = obj_ce;
if (object_pp) {
fcic.called_scope = Z_OBJCE_PP(object_pp);
if (object) {
fcic.called_scope = Z_OBJCE_P(object);
} else if (obj_ce &&
!(EG(called_scope) &&
instanceof_function(EG(called_scope), obj_ce TSRMLS_CC))) {
@ -93,25 +91,23 @@ ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend
} else {
fcic.called_scope = EG(called_scope);
}
fcic.object_ptr = object_pp ? *object_pp : NULL;
fcic.object_ptr = object;
result = zend_call_function(&fci, &fcic TSRMLS_CC);
}
if (result == FAILURE) {
/* error at c-level */
if (!obj_ce) {
obj_ce = object_pp ? Z_OBJCE_PP(object_pp) : NULL;
obj_ce = object ? Z_OBJCE_P(object) : NULL;
}
if (!EG(exception)) {
zend_error(E_CORE_ERROR, "Couldn't execute method %s%s%s", obj_ce ? obj_ce->name : "", obj_ce ? "::" : "", function_name);
zend_error(E_CORE_ERROR, "Couldn't execute method %s%s%s", obj_ce ? obj_ce->name->val : "", obj_ce ? "::" : "", function_name);
}
}
if (!retval_ptr_ptr) {
if (retval) {
zval_ptr_dtor(&retval);
}
if (!retval_ptr) {
zval_ptr_dtor(&retval);
return NULL;
}
return *retval_ptr_ptr;
return retval_ptr;
}
/* }}} */
@ -120,9 +116,9 @@ ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend
/* {{{ zend_user_it_new_iterator */
ZEND_API zval *zend_user_it_new_iterator(zend_class_entry *ce, zval *object TSRMLS_DC)
{
zval *retval;
zval retval;
return zend_call_method_with_0_params(&object, ce, &ce->iterator_funcs.zf_new_iterator, "getiterator", &retval);
return zend_call_method_with_0_params(object, ce, &ce->iterator_funcs.zf_new_iterator, "getiterator", &retval);
}
/* }}} */
@ -133,7 +129,7 @@ ZEND_API void zend_user_it_invalidate_current(zend_object_iterator *_iter TSRMLS
zend_user_iterator *iter = (zend_user_iterator*)_iter;
if (iter->value) {
zval_ptr_dtor(&iter->value);
zval_ptr_dtor(iter->value);
iter->value = NULL;
}
}
@ -146,7 +142,7 @@ static void zend_user_it_dtor(zend_object_iterator *_iter TSRMLS_DC)
zval *object = (zval*)iter->it.data;
zend_user_it_invalidate_current(_iter TSRMLS_CC);
zval_ptr_dtor(&object);
zval_ptr_dtor(object);
efree(iter);
}
/* }}} */
@ -157,12 +153,12 @@ ZEND_API int zend_user_it_valid(zend_object_iterator *_iter TSRMLS_DC)
if (_iter) {
zend_user_iterator *iter = (zend_user_iterator*)_iter;
zval *object = (zval*)iter->it.data;
zval *more;
zval more;
int result;
zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_valid, "valid", &more);
if (more) {
result = i_zend_is_true(more TSRMLS_CC);
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs.zf_valid, "valid", &more);
if (Z_TYPE(more) != IS_UNDEF) {
result = i_zend_is_true(&more TSRMLS_CC);
zval_ptr_dtor(&more);
return result ? SUCCESS : FAILURE;
}
@ -172,15 +168,15 @@ ZEND_API int zend_user_it_valid(zend_object_iterator *_iter TSRMLS_DC)
/* }}} */
/* {{{ zend_user_it_get_current_data */
ZEND_API void zend_user_it_get_current_data(zend_object_iterator *_iter, zval ***data TSRMLS_DC)
ZEND_API zval *zend_user_it_get_current_data(zend_object_iterator *_iter TSRMLS_DC)
{
zend_user_iterator *iter = (zend_user_iterator*)_iter;
zval *object = (zval*)iter->it.data;
if (!iter->value) {
zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_current, "current", &iter->value);
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs.zf_current, "current", iter->value);
}
*data = &iter->value;
return iter->value;
}
/* }}} */
@ -199,15 +195,15 @@ ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *ke
{
zend_user_iterator *iter = (zend_user_iterator*)_iter;
zval *object = (zval*)iter->it.data;
zval *retval;
zval retval;
zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_key, "key", &retval);
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs.zf_key, "key", &retval);
if (retval) {
ZVAL_ZVAL(key, retval, 1, 1);
if (Z_TYPE(retval) != IS_UNDEF) {
ZVAL_ZVAL(key, &retval, 1, 1);
} else {
if (!EG(exception)) {
zend_error(E_WARNING, "Nothing returned from %s::key()", iter->ce->name);
zend_error(E_WARNING, "Nothing returned from %s::key()", iter->ce->name->val);
}
ZVAL_LONG(key, 0);
@ -221,7 +217,7 @@ ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter TSRMLS_DC)
zval *object = (zval*)iter->it.data;
zend_user_it_invalidate_current(_iter TSRMLS_CC);
zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_next, "next", NULL);
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs.zf_next, "next", NULL);
}
/* }}} */
@ -232,7 +228,7 @@ ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter TSRMLS_DC)
zval *object = (zval*)iter->it.data;
zend_user_it_invalidate_current(_iter TSRMLS_CC);
zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_rewind, "rewind", NULL);
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs.zf_rewind, "rewind", NULL);
}
/* }}} */
@ -279,13 +275,13 @@ ZEND_API zend_object_iterator *zend_user_it_get_new_iterator(zend_class_entry *c
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Objects returned by %s::getIterator() must be traversable or implement interface Iterator", ce ? ce->name : Z_OBJCE_P(object)->name);
}
if (iterator) {
zval_ptr_dtor(&iterator);
zval_ptr_dtor(iterator);
}
return NULL;
}
new_iterator = ce_it->get_iterator(ce_it, iterator, by_ref TSRMLS_CC);
zval_ptr_dtor(&iterator);
zval_ptr_dtor(iterator);
return new_iterator;
}
/* }}} */
@ -305,10 +301,10 @@ static int zend_implement_traversable(zend_class_entry *interface, zend_class_en
}
}
zend_error(E_CORE_ERROR, "Class %s must implement interface %s as part of either %s or %s",
class_type->name,
zend_ce_traversable->name,
zend_ce_iterator->name,
zend_ce_aggregate->name);
class_type->name->val,
zend_ce_traversable->name->val,
zend_ce_iterator->name->val,
zend_ce_aggregate->name->val);
return FAILURE;
}
/* }}} */
@ -328,9 +324,9 @@ static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entr
for (i = 0; i < class_type->num_interfaces; i++) {
if (class_type->interfaces[i] == zend_ce_iterator) {
zend_error(E_ERROR, "Class %s cannot implement both %s and %s at the same time",
class_type->name,
interface->name,
zend_ce_iterator->name);
class_type->name->val,
interface->name->val,
zend_ce_iterator->name->val);
return FAILURE;
}
if (class_type->interfaces[i] == zend_ce_traversable) {
@ -360,9 +356,9 @@ static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry
/* c-level get_iterator cannot be changed */
if (class_type->get_iterator == zend_user_it_get_new_iterator) {
zend_error(E_ERROR, "Class %s cannot implement both %s and %s at the same time",
class_type->name,
interface->name,
zend_ce_aggregate->name);
class_type->name->val,
interface->name->val,
zend_ce_aggregate->name->val);
}
return FAILURE;
}
@ -400,23 +396,23 @@ static int zend_implement_arrayaccess(zend_class_entry *interface, zend_class_en
ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC)
{
zend_class_entry * ce = Z_OBJCE_P(object);
zval *retval;
zval retval;
int result;
zend_call_method_with_0_params(&object, ce, &ce->serialize_func, "serialize", &retval);
zend_call_method_with_0_params(object, ce, &ce->serialize_func, "serialize", &retval);
if (!retval || EG(exception)) {
if (Z_TYPE(retval) == IS_UNDEF || EG(exception)) {
result = FAILURE;
} else {
switch(Z_TYPE_P(retval)) {
switch(Z_TYPE(retval)) {
case IS_NULL:
/* we could also make this '*buf_len = 0' but this allows to skip variables */
zval_ptr_dtor(&retval);
return FAILURE;
case IS_STRING:
*buffer = (unsigned char*)estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
*buf_len = Z_STRLEN_P(retval);
*buffer = (unsigned char*)estrndup(Z_STRVAL(retval), Z_STRLEN(retval));
*buf_len = Z_STRLEN(retval);
result = SUCCESS;
break;
default: /* failure */
@ -434,16 +430,15 @@ ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, zend_uint
/* }}} */
/* {{{ zend_user_unserialize */
ZEND_API int zend_user_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC)
ZEND_API int zend_user_unserialize(zval *object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC)
{
zval * zdata;
zval zdata;
object_init_ex(*object, ce);
object_init_ex(object, ce);
MAKE_STD_ZVAL(zdata);
ZVAL_STRINGL(zdata, (char*)buf, buf_len, 1);
ZVAL_STRINGL(&zdata, (char*)buf, buf_len);
zend_call_method_with_1_params(object, ce, &ce->unserialize_func, "unserialize", NULL, zdata);
zend_call_method_with_1_params(object, ce, &ce->unserialize_func, "unserialize", NULL, &zdata);
zval_ptr_dtor(&zdata);
@ -463,9 +458,9 @@ ZEND_API int zend_class_serialize_deny(zval *object, unsigned char **buffer, zen
}
/* }}} */
ZEND_API int zend_class_unserialize_deny(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC) /* {{{ */
ZEND_API int zend_class_unserialize_deny(zval *object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC) /* {{{ */
{
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Unserialization of '%s' is not allowed", ce->name);
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Unserialization of '%s' is not allowed", ce->name->val);
return FAILURE;
}
/* }}} */

View file

@ -38,7 +38,7 @@ typedef struct _zend_user_iterator {
zval *value;
} zend_user_iterator;
ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, const char *function_name, int function_name_len, zval **retval_ptr_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC);
ZEND_API zval* zend_call_method(zval *object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, const char *function_name, int function_name_len, zval *retval, int param_count, zval* arg1, zval* arg2 TSRMLS_DC);
#define zend_call_method_with_0_params(obj, obj_ce, fn_proxy, function_name, retval) \
zend_call_method(obj, obj_ce, fn_proxy, function_name, sizeof(function_name)-1, retval, 0, NULL, NULL TSRMLS_CC)
@ -52,7 +52,7 @@ ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend
ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter TSRMLS_DC);
ZEND_API int zend_user_it_valid(zend_object_iterator *_iter TSRMLS_DC);
ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *key TSRMLS_DC);
ZEND_API void zend_user_it_get_current_data(zend_object_iterator *_iter, zval ***data TSRMLS_DC);
ZEND_API zval *zend_user_it_get_current_data(zend_object_iterator *_iter TSRMLS_DC);
ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter TSRMLS_DC);
ZEND_API void zend_user_it_invalidate_current(zend_object_iterator *_iter TSRMLS_DC);
@ -62,10 +62,10 @@ ZEND_API zend_object_iterator *zend_user_it_get_new_iterator(zend_class_entry *c
ZEND_API void zend_register_interfaces(TSRMLS_D);
ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC);
ZEND_API int zend_user_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC);
ZEND_API int zend_user_unserialize(zval *object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC);
ZEND_API int zend_class_serialize_deny(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC);
ZEND_API int zend_class_unserialize_deny(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC);
ZEND_API int zend_class_unserialize_deny(zval *object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC);
END_EXTERN_C()

View file

@ -51,11 +51,11 @@ static zend_object_handlers iterator_object_handlers = {
ZEND_API void zend_register_iterator_wrapper(TSRMLS_D)
{
INIT_CLASS_ENTRY(zend_iterator_class_entry, "__iterator_wrapper", NULL);
str_free(zend_iterator_class_entry.name);
zend_iterator_class_entry.name = "__iterator_wrapper";
//??? STR_RELEASE(zend_iterator_class_entry.name);
//??? zend_iterator_class_entry.name = STR_INIT("__iterator_wrapper", sizeof("__iterator_wrapper")-1, 0);
}
static void iter_wrapper_dtor(void *object, zend_object_handle handle TSRMLS_DC)
static void iter_wrapper_dtor(zend_object *object TSRMLS_DC)
{
zend_object_iterator *iter = (zend_object_iterator*)object;
iter->funcs->dtor(iter TSRMLS_CC);
@ -63,6 +63,9 @@ static void iter_wrapper_dtor(void *object, zend_object_handle handle TSRMLS_DC)
ZEND_API zval *zend_iterator_wrap(zend_object_iterator *iter TSRMLS_DC)
{
//???
return NULL;
#if 0
zval *wrapped;
MAKE_STD_ZVAL(wrapped);
@ -71,6 +74,7 @@ ZEND_API zval *zend_iterator_wrap(zend_object_iterator *iter TSRMLS_DC)
Z_OBJ_HT_P(wrapped) = &iterator_object_handlers;
return wrapped;
#endif
}
ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap(
@ -79,7 +83,7 @@ ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap(
switch (Z_TYPE_P(array_ptr)) {
case IS_OBJECT:
if (Z_OBJ_HT_P(array_ptr) == &iterator_object_handlers) {
*iter = (zend_object_iterator *)zend_object_store_get_object(array_ptr TSRMLS_CC);
*iter = (zend_object_iterator *)Z_OBJ_P(array_ptr);
return ZEND_ITER_OBJECT;
}
if (Z_OBJPROP_P(array_ptr)) {

View file

@ -36,7 +36,7 @@ typedef struct _zend_object_iterator_funcs {
int (*valid)(zend_object_iterator *iter TSRMLS_DC);
/* fetch the item data for the current element */
void (*get_current_data)(zend_object_iterator *iter, zval ***data TSRMLS_DC);
zval *(*get_current_data)(zend_object_iterator *iter TSRMLS_DC);
/* fetch the key for the current element (optional, may be NULL). The key
* should be written into the provided zval* using the ZVAL_* macros. If

View file

@ -806,8 +806,8 @@ expr_without_variable:
| expr '%' expr { zend_do_binary_op(ZEND_MOD, &$$, &$1, &$3 TSRMLS_CC); }
| expr T_SL expr { zend_do_binary_op(ZEND_SL, &$$, &$1, &$3 TSRMLS_CC); }
| expr T_SR expr { zend_do_binary_op(ZEND_SR, &$$, &$1, &$3 TSRMLS_CC); }
| '+' expr %prec T_INC { ZVAL_LONG(&$1.u.constant, 0); if ($2.op_type == IS_CONST) { add_function(&$2.u.constant, &$1.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } else { $1.op_type = IS_CONST; INIT_PZVAL(&$1.u.constant); zend_do_binary_op(ZEND_ADD, &$$, &$1, &$2 TSRMLS_CC); } }
| '-' expr %prec T_INC { ZVAL_LONG(&$1.u.constant, 0); if ($2.op_type == IS_CONST) { sub_function(&$2.u.constant, &$1.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } else { $1.op_type = IS_CONST; INIT_PZVAL(&$1.u.constant); zend_do_binary_op(ZEND_SUB, &$$, &$1, &$2 TSRMLS_CC); } }
| '+' expr %prec T_INC { ZVAL_LONG(&$1.u.constant, 0); if ($2.op_type == IS_CONST) { add_function(&$2.u.constant, &$1.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } else { $1.op_type = IS_CONST; zend_do_binary_op(ZEND_ADD, &$$, &$1, &$2 TSRMLS_CC); } }
| '-' expr %prec T_INC { ZVAL_LONG(&$1.u.constant, 0); if ($2.op_type == IS_CONST) { sub_function(&$2.u.constant, &$1.u.constant, &$2.u.constant TSRMLS_CC); $$ = $2; } else { $1.op_type = IS_CONST; zend_do_binary_op(ZEND_SUB, &$$, &$1, &$2 TSRMLS_CC); } }
| '!' expr { zend_do_unary_op(ZEND_BOOL_NOT, &$$, &$2 TSRMLS_CC); }
| '~' expr { zend_do_unary_op(ZEND_BW_NOT, &$$, &$2 TSRMLS_CC); }
| expr T_IS_IDENTICAL expr { zend_do_binary_op(ZEND_IS_IDENTICAL, &$$, &$1, &$3 TSRMLS_CC); }
@ -903,16 +903,16 @@ function_call:
;
class_name:
T_STATIC { $$.op_type = IS_CONST; ZVAL_STRINGL(&$$.u.constant, "static", sizeof("static")-1, 1);}
T_STATIC { $$.op_type = IS_CONST; ZVAL_STRINGL(&$$.u.constant, "static", sizeof("static")-1);}
| namespace_name { $$ = $1; }
| T_NAMESPACE T_NS_SEPARATOR namespace_name { $$.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$$.u.constant); zend_do_build_namespace_name(&$$, &$$, &$3 TSRMLS_CC); }
| T_NS_SEPARATOR namespace_name { char *tmp = estrndup(Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); memcpy(&(tmp[1]), Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); tmp[0] = '\\'; efree(Z_STRVAL($2.u.constant)); Z_STRVAL($2.u.constant) = tmp; ++Z_STRLEN($2.u.constant); $$ = $2; }
| T_NS_SEPARATOR namespace_name { zval tmp; ZVAL_STR(&tmp, STR_ALLOC(Z_STRLEN($2.u.constant)+1, 0)); Z_STRVAL(tmp)[0] = '\\'; memcpy(Z_STRVAL(tmp) + 1, Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); if (Z_DELREF($2.u.constant) == 0) {efree(Z_STR($2.u.constant));} Z_STR($2.u.constant) = Z_STR(tmp); $$ = $2; }
;
fully_qualified_class_name:
namespace_name { $$ = $1; }
| T_NAMESPACE T_NS_SEPARATOR namespace_name { $$.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$$.u.constant); zend_do_build_namespace_name(&$$, &$$, &$3 TSRMLS_CC); }
| T_NS_SEPARATOR namespace_name { char *tmp = estrndup(Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); memcpy(&(tmp[1]), Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); tmp[0] = '\\'; efree(Z_STRVAL($2.u.constant)); Z_STRVAL($2.u.constant) = tmp; ++Z_STRLEN($2.u.constant); $$ = $2; }
| T_NS_SEPARATOR namespace_name { zval tmp; ZVAL_STR(&tmp, STR_ALLOC(Z_STRLEN($2.u.constant)+1, 0)); Z_STRVAL(tmp)[0] = '\\'; memcpy(Z_STRVAL(tmp) + 1, Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); if (Z_DELREF($2.u.constant) == 0) {efree(Z_STR($2.u.constant));} Z_STR($2.u.constant) = Z_STR(tmp); $$ = $2; }
;
@ -948,7 +948,7 @@ exit_expr:
;
backticks_expr:
/* empty */ { ZVAL_EMPTY_STRING(&$$.u.constant); INIT_PZVAL(&$$.u.constant); $$.op_type = IS_CONST; }
/* empty */ { ZVAL_EMPTY_STRING(&$$.u.constant); $$.op_type = IS_CONST; }
| T_ENCAPSED_AND_WHITESPACE { $$ = $1; }
| encaps_list { $$ = $1; }
;
@ -972,7 +972,7 @@ common_scalar:
| T_FUNC_C { $$ = $1; }
| T_NS_C { $$ = $1; }
| T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC { $$ = $2; }
| T_START_HEREDOC T_END_HEREDOC { ZVAL_EMPTY_STRING(&$$.u.constant); INIT_PZVAL(&$$.u.constant); $$.op_type = IS_CONST; }
| T_START_HEREDOC T_END_HEREDOC { ZVAL_EMPTY_STRING(&$$.u.constant); $$.op_type = IS_CONST; }
;
static_class_constant:
@ -990,7 +990,7 @@ static_scalar_value:
| static_class_name_scalar { $$.u.ast = zend_ast_create_constant(&$1.u.constant); }
| namespace_name { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_CT, 1 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); }
| T_NAMESPACE T_NS_SEPARATOR namespace_name { $$.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$$.u.constant); zend_do_build_namespace_name(&$$, &$$, &$3 TSRMLS_CC); $3 = $$; zend_do_fetch_constant(&$$, NULL, &$3, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); }
| T_NS_SEPARATOR namespace_name { char *tmp = estrndup(Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); memcpy(&(tmp[1]), Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); tmp[0] = '\\'; efree(Z_STRVAL($2.u.constant)); Z_STRVAL($2.u.constant) = tmp; ++Z_STRLEN($2.u.constant); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); }
| T_NS_SEPARATOR namespace_name { zval tmp; ZVAL_STR(&tmp, STR_ALLOC(Z_STRLEN($2.u.constant)+1, 0)); Z_STRVAL(tmp)[0] = '\\'; memcpy(Z_STRVAL(tmp) + 1, Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); if (Z_DELREF($2.u.constant) == 0) {efree(Z_STR($2.u.constant));} Z_STR($2.u.constant) = Z_STR(tmp); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); }
| static_class_constant { $$.u.ast = zend_ast_create_constant(&$1.u.constant); }
| T_CLASS_C { $$.u.ast = zend_ast_create_constant(&$1.u.constant); }
| static_operation { $$ = $1; }
@ -1037,7 +1037,7 @@ scalar:
| class_constant { $$ = $1; }
| namespace_name { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_RT, 1 TSRMLS_CC); }
| T_NAMESPACE T_NS_SEPARATOR namespace_name { $$.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$$.u.constant); zend_do_build_namespace_name(&$$, &$$, &$3 TSRMLS_CC); $3 = $$; zend_do_fetch_constant(&$$, NULL, &$3, ZEND_RT, 0 TSRMLS_CC); }
| T_NS_SEPARATOR namespace_name { char *tmp = estrndup(Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); memcpy(&(tmp[1]), Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); tmp[0] = '\\'; efree(Z_STRVAL($2.u.constant)); Z_STRVAL($2.u.constant) = tmp; ++Z_STRLEN($2.u.constant); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_RT, 0 TSRMLS_CC); }
| T_NS_SEPARATOR namespace_name { zval tmp; ZVAL_STR(&tmp, STR_ALLOC(Z_STRLEN($2.u.constant)+1, 0)); Z_STRVAL(tmp)[0] = '\\'; memcpy(Z_STRVAL(tmp) + 1, Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); if (Z_DELREF($2.u.constant) == 0) {efree(Z_STR($2.u.constant));} Z_STR($2.u.constant) = Z_STR(tmp); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_RT, 0 TSRMLS_CC); }
| common_scalar { $$ = $1; }
| '"' encaps_list '"' { $$ = $2; }
| T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = $2; }
@ -1046,7 +1046,7 @@ scalar:
static_array_pair_list:
/* empty */ { $$.op_type = IS_CONST; INIT_PZVAL(&$$.u.constant); array_init(&$$.u.constant); }
/* empty */ { $$.op_type = IS_CONST; array_init(&$$.u.constant); }
| non_empty_static_array_pair_list possible_comma { $$ = $1; }
;
@ -1058,8 +1058,8 @@ possible_comma:
non_empty_static_array_pair_list:
non_empty_static_array_pair_list ',' static_scalar T_DOUBLE_ARROW static_scalar { zend_do_add_static_array_element(&$$, &$3, &$5); }
| non_empty_static_array_pair_list ',' static_scalar { zend_do_add_static_array_element(&$$, NULL, &$3); }
| static_scalar T_DOUBLE_ARROW static_scalar { $$.op_type = IS_CONST; INIT_PZVAL(&$$.u.constant); array_init(&$$.u.constant); zend_do_add_static_array_element(&$$, &$1, &$3); }
| static_scalar { $$.op_type = IS_CONST; INIT_PZVAL(&$$.u.constant); array_init(&$$.u.constant); zend_do_add_static_array_element(&$$, NULL, &$1); }
| static_scalar T_DOUBLE_ARROW static_scalar { $$.op_type = IS_CONST; array_init(&$$.u.constant); zend_do_add_static_array_element(&$$, &$1, &$3); }
| static_scalar { $$.op_type = IS_CONST; array_init(&$$.u.constant); zend_do_add_static_array_element(&$$, NULL, &$1); }
;
expr:

File diff suppressed because it is too large Load diff

View file

@ -35,7 +35,7 @@ typedef struct _zend_lex_state {
zend_file_handle *in;
uint lineno;
char *filename;
zend_string *filename;
/* original (unfiltered) script */
unsigned char *script_org;

View file

@ -112,9 +112,9 @@ do { \
} \
}
/* To save initial string length after scanning to first variable, CG(doc_comment_len) can be reused */
#define SET_DOUBLE_QUOTES_SCANNED_LENGTH(len) CG(doc_comment_len) = (len)
#define GET_DOUBLE_QUOTES_SCANNED_LENGTH() CG(doc_comment_len)
/* To save initial string length after scanning to first variable */
#define SET_DOUBLE_QUOTES_SCANNED_LENGTH(len) SCNG(scanned_string_len) = (len)
#define GET_DOUBLE_QUOTES_SCANNED_LENGTH() SCNG(scanned_string_len)
#define IS_LABEL_START(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z') || (c) == '_' || (c) >= 0x7F)
@ -179,7 +179,6 @@ void startup_scanner(TSRMLS_D)
{
CG(parse_error) = 0;
CG(doc_comment) = NULL;
CG(doc_comment_len) = 0;
zend_stack_init(&SCNG(state_stack));
zend_ptr_stack_init(&SCNG(heredoc_label_stack));
}
@ -534,7 +533,7 @@ ZEND_API int open_file_for_scanning(zend_file_handle *file_handle TSRMLS_DC)
file_path = file_handle->filename;
}
zend_set_compiled_filename(file_path TSRMLS_CC);
zend_set_compiled_filename(STR_INIT(file_path, strlen(file_path), 0) TSRMLS_CC);
if (CG(start_lineno)) {
CG(zend_lineno) = CG(start_lineno);
@ -562,7 +561,6 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSR
zend_bool original_in_compilation = CG(in_compilation);
retval_znode.op_type = IS_CONST;
INIT_PZVAL(&retval_znode.u.constant);
ZVAL_LONG(&retval_znode.u.constant, 1);
zend_save_lexical_state(&original_lex_state TSRMLS_CC);
@ -628,13 +626,11 @@ zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC)
retval = zend_compile_file(&file_handle, type TSRMLS_CC);
if (retval && file_handle.handle.stream.handle) {
int dummy = 1;
if (!file_handle.opened_path) {
file_handle.opened_path = opened_path = estrndup(Z_STRVAL_P(filename), Z_STRLEN_P(filename));
}
zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL);
zend_hash_str_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path));
if (opened_path) {
efree(opened_path);
@ -654,7 +650,16 @@ ZEND_API int zend_prepare_string_for_scanning(zval *str, char *filename TSRMLS_D
size_t size;
/* enforce ZEND_MMAP_AHEAD trailing NULLs for flex... */
Z_STRVAL_P(str) = str_erealloc(Z_STRVAL_P(str), Z_STRLEN_P(str) + ZEND_MMAP_AHEAD);
if (Z_REFCOUNT_P(str) == 1) {
Z_STR_P(str) = STR_EREALLOC(Z_STR_P(str), Z_STRLEN_P(str) + ZEND_MMAP_AHEAD);
} else {
zend_string *tmp;
tmp = STR_ALLOC(Z_STRLEN_P(str) + ZEND_MMAP_AHEAD, 0);
memcpy(tmp->val, Z_STRVAL_P(str), Z_STRLEN_P(str) + 1);
Z_DELREF_P(str);
Z_STR_P(str) = tmp;
}
memset(Z_STRVAL_P(str) + Z_STRLEN_P(str), 0, ZEND_MMAP_AHEAD);
SCNG(yy_in) = NULL;
@ -682,7 +687,7 @@ ZEND_API int zend_prepare_string_for_scanning(zval *str, char *filename TSRMLS_D
yy_scan_buffer(buf, size TSRMLS_CC);
zend_set_compiled_filename(filename TSRMLS_CC);
zend_set_compiled_filename(STR_INIT(filename, strlen(filename), 0) TSRMLS_CC);
CG(zend_lineno) = 1;
CG(increment_lineno) = 0;
RESET_DOC_COMMENT();
@ -863,8 +868,7 @@ ZEND_API void zend_multibyte_yyinput_again(zend_encoding_filter old_input_filter
SCNG(output_filter)((unsigned char **)&Z_STRVAL_P(zendlval), &sz, (unsigned char *)yytext, (size_t)yyleng TSRMLS_CC); \
Z_STRLEN_P(zendlval) = sz; \
} else { \
Z_STRVAL_P(zendlval) = (char *) estrndup(yytext, yyleng); \
Z_STRLEN_P(zendlval) = yyleng; \
ZVAL_STRINGL(zendlval, yytext, yyleng); \
}
static void zend_scan_escape_string(zval *zendlval, char *str, int len, char quote_type TSRMLS_DC)
@ -872,7 +876,7 @@ static void zend_scan_escape_string(zval *zendlval, char *str, int len, char quo
register char *s, *t;
char *end;
ZVAL_STRINGL(zendlval, str, len, 1);
ZVAL_STRINGL(zendlval, str, len);
/* convert escape sequences */
s = t = Z_STRVAL_P(zendlval);
@ -1173,7 +1177,7 @@ NEWLINE ("\r"|"\n"|"\r\n")
}
<ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY>{WHITESPACE}+ {
ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */
ZVAL_STRINGL(zendlval, yytext, yyleng);
HANDLE_NEWLINES(yytext, yyleng);
return T_WHITESPACE;
}
@ -1559,13 +1563,13 @@ NEWLINE ("\r"|"\n"|"\r\n")
if (yyleng < MAX_LENGTH_OF_LONG - 1 || (yyleng == MAX_LENGTH_OF_LONG - 1 && strcmp(yytext, long_min_digits) < 0)) {
ZVAL_LONG(zendlval, strtol(yytext, NULL, 10));
} else {
ZVAL_STRINGL(zendlval, yytext, yyleng, 1);
ZVAL_STRINGL(zendlval, yytext, yyleng);
}
return T_NUM_STRING;
}
<ST_VAR_OFFSET>{LNUM}|{HNUM}|{BNUM} { /* Offset must be treated as a string */
ZVAL_STRINGL(zendlval, yytext, yyleng, 1);
ZVAL_STRINGL(zendlval, yytext, yyleng);
return T_NUM_STRING;
}
@ -1579,12 +1583,12 @@ NEWLINE ("\r"|"\n"|"\r\n")
if (ce && ZEND_ACC_TRAIT == (ce->ce_flags & ZEND_ACC_TRAIT)) {
/* We create a special __CLASS__ constant that is going to be resolved
at run-time */
Z_STRLEN_P(zendlval) = sizeof("__CLASS__")-1;
Z_STRVAL_P(zendlval) = estrndup("__CLASS__", Z_STRLEN_P(zendlval));
zendlval->type = IS_CONSTANT;
ZVAL_STRINGL(zendlval, "__CLASS__", sizeof("__CLASS__") - 1);
Z_TYPE_P(zendlval) = IS_CONSTANT;
} else {
if (ce && ce->name) {
ZVAL_STRINGL(zendlval, ce->name, ce->name_length, 1);
ZVAL_STR(zendlval, ce->name);
Z_ADDREF_P(zendlval);
} else {
ZVAL_EMPTY_STRING(zendlval);
}
@ -1595,7 +1599,8 @@ NEWLINE ("\r"|"\n"|"\r\n")
<ST_IN_SCRIPTING>"__TRAIT__" {
zend_class_entry *ce = CG(active_class_entry);
if (ce && ce->name && ZEND_ACC_TRAIT == (ce->ce_flags & ZEND_ACC_TRAIT)) {
ZVAL_STRINGL(zendlval, ce->name, ce->name_length, 1);
ZVAL_STR(zendlval, ce->name);
Z_ADDREF_P(zendlval);
} else {
ZVAL_EMPTY_STRING(zendlval);
}
@ -1605,7 +1610,8 @@ NEWLINE ("\r"|"\n"|"\r\n")
<ST_IN_SCRIPTING>"__FUNCTION__" {
zend_op_array *op_array = CG(active_op_array);
if (op_array && op_array->function_name) {
ZVAL_STRING(zendlval, op_array->function_name, 1);
ZVAL_STR(zendlval, op_array->function_name);
Z_ADDREF_P(zendlval);
} else {
ZVAL_EMPTY_STRING(zendlval);
}
@ -1613,10 +1619,10 @@ NEWLINE ("\r"|"\n"|"\r\n")
}
<ST_IN_SCRIPTING>"__METHOD__" {
const char *class_name = CG(active_class_entry) ? CG(active_class_entry)->name : NULL;
const char *func_name = CG(active_op_array)? CG(active_op_array)->function_name : NULL;
const char *class_name = CG(active_class_entry) ? CG(active_class_entry)->name->val : NULL;
const char *func_name = CG(active_op_array)? CG(active_op_array)->function_name->val : NULL;
Z_STRLEN_P(zendlval) = zend_spprintf(&Z_STRVAL_P(zendlval), 0, "%s%s%s",
Z_STRLEN_P(zendlval) = zend_spprintf((char**)&Z_STRVAL_P(zendlval), 0, "%s%s%s",
class_name ? class_name : "",
class_name && func_name ? "::" : "",
func_name ? func_name : ""
@ -1631,44 +1637,43 @@ NEWLINE ("\r"|"\n"|"\r\n")
}
<ST_IN_SCRIPTING>"__FILE__" {
char *filename = zend_get_compiled_filename(TSRMLS_C);
zend_string *filename = zend_get_compiled_filename(TSRMLS_C);
if (!filename) {
filename = "";
filename = STR_EMPTY_ALLOC();
}
ZVAL_STRING(zendlval, filename, 1);
ZVAL_STR(zendlval, filename);
return T_FILE;
}
<ST_IN_SCRIPTING>"__DIR__" {
char *filename = zend_get_compiled_filename(TSRMLS_C);
const size_t filename_len = strlen(filename);
char *dirname;
zend_string *filename = zend_get_compiled_filename(TSRMLS_C);
zend_string *dirname;
if (!filename) {
filename = "";
filename = STR_EMPTY_ALLOC();
}
dirname = estrndup(filename, filename_len);
zend_dirname(dirname, filename_len);
dirname = STR_DUP(filename, 0);
zend_dirname(dirname->val, dirname->len);
if (strcmp(dirname, ".") == 0) {
dirname = erealloc(dirname, MAXPATHLEN);
if (strcmp(dirname->val, ".") == 0) {
dirname = STR_EREALLOC(dirname, MAXPATHLEN);
#if HAVE_GETCWD
VCWD_GETCWD(dirname, MAXPATHLEN);
VCWD_GETCWD(dirname->val, MAXPATHLEN);
#elif HAVE_GETWD
VCWD_GETWD(dirname);
VCWD_GETWD(dirname->val);
#endif
}
ZVAL_STRING(zendlval, dirname, 0);
dirname->len = strlen(dirname->val);
ZVAL_STR(zendlval, dirname);
return T_DIR;
}
<ST_IN_SCRIPTING>"__NAMESPACE__" {
if (CG(current_namespace)) {
*zendlval = *CG(current_namespace);
zval_copy_ctor(zendlval);
if (Z_TYPE(CG(current_namespace)) != IS_UNDEF) {
ZVAL_DUP(zendlval, &CG(current_namespace));
} else {
ZVAL_EMPTY_STRING(zendlval);
}
@ -1685,7 +1690,7 @@ NEWLINE ("\r"|"\n"|"\r\n")
}
HANDLE_NEWLINES(yytext, yyleng);
ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */
ZVAL_STRINGL(zendlval, yytext, yyleng);
BEGIN(ST_IN_SCRIPTING);
return T_OPEN_TAG;
}
@ -1693,7 +1698,7 @@ NEWLINE ("\r"|"\n"|"\r\n")
<INITIAL>"<%=" {
if (CG(asp_tags)) {
ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */
ZVAL_STRINGL(zendlval, yytext, yyleng);
BEGIN(ST_IN_SCRIPTING);
return T_OPEN_TAG_WITH_ECHO;
} else {
@ -1703,7 +1708,7 @@ NEWLINE ("\r"|"\n"|"\r\n")
<INITIAL>"<?=" {
ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */
ZVAL_STRINGL(zendlval, yytext, yyleng);
BEGIN(ST_IN_SCRIPTING);
return T_OPEN_TAG_WITH_ECHO;
}
@ -1711,7 +1716,7 @@ NEWLINE ("\r"|"\n"|"\r\n")
<INITIAL>"<%" {
if (CG(asp_tags)) {
ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */
ZVAL_STRINGL(zendlval, yytext, yyleng);
BEGIN(ST_IN_SCRIPTING);
return T_OPEN_TAG;
} else {
@ -1721,7 +1726,7 @@ NEWLINE ("\r"|"\n"|"\r\n")
<INITIAL>"<?php"([ \t]|{NEWLINE}) {
ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */
ZVAL_STRINGL(zendlval, yytext, yyleng);
HANDLE_NEWLINE(yytext[yyleng-1]);
BEGIN(ST_IN_SCRIPTING);
return T_OPEN_TAG;
@ -1730,7 +1735,7 @@ NEWLINE ("\r"|"\n"|"\r\n")
<INITIAL>"<?" {
if (CG(short_tags)) {
ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */
ZVAL_STRINGL(zendlval, yytext, yyleng);
BEGIN(ST_IN_SCRIPTING);
return T_OPEN_TAG;
} else {
@ -1789,11 +1794,10 @@ inline_html:
if (readsize < yyleng) {
yyless(readsize);
}
zendlval->type = IS_STRING;
} else {
Z_STRVAL_P(zendlval) = (char *) estrndup(yytext, yyleng);
Z_STRLEN_P(zendlval) = yyleng;
ZVAL_STRINGL(zendlval, yytext, yyleng);
}
zendlval->type = IS_STRING;
HANDLE_NEWLINES(yytext, yyleng);
return T_INLINE_HTML;
}
@ -1910,8 +1914,7 @@ inline_html:
HANDLE_NEWLINES(yytext, yyleng);
if (doc_com) {
CG(doc_comment) = estrndup(yytext, yyleng);
CG(doc_comment_len) = yyleng;
CG(doc_comment) = STR_INIT(yytext, yyleng, 0);
return T_DOC_COMMENT;
}
@ -1919,7 +1922,7 @@ inline_html:
}
<ST_IN_SCRIPTING>("?>"|"</script"{WHITESPACE}*">"){NEWLINE}? {
ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */
ZVAL_STRINGL(zendlval, yytext, yyleng);
BEGIN(INITIAL);
return T_CLOSE_TAG; /* implicit ';' at php-end tag */
}
@ -1928,7 +1931,7 @@ inline_html:
<ST_IN_SCRIPTING>"%>"{NEWLINE}? {
if (CG(asp_tags)) {
BEGIN(INITIAL);
ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */
ZVAL_STRINGL(zendlval, yytext, yyleng);
return T_CLOSE_TAG; /* implicit ';' at php-end tag */
} else {
yyless(1);
@ -1962,7 +1965,7 @@ inline_html:
}
}
ZVAL_STRINGL(zendlval, yytext+bprefix+1, yyleng-bprefix-2, 1);
ZVAL_STRINGL(zendlval, yytext+bprefix+1, yyleng-bprefix-2);
/* convert escape sequences */
s = t = Z_STRVAL_P(zendlval);

View file

@ -1,4 +1,4 @@
/* Generated by re2c 0.13.5 on Sun Dec 22 13:03:33 2013 */
/* Generated by re2c 0.13.5 */
#line 3 "Zend/zend_language_scanner_defs.h"
enum YYCONDTYPE {

View file

@ -31,88 +31,46 @@ ZEND_API int le_index_ptr;
/* true global */
static HashTable list_destructors;
ZEND_API int zend_list_insert(void *ptr, int type TSRMLS_DC)
ZEND_API zval *zend_list_insert(void *ptr, int type TSRMLS_DC)
{
int index;
zend_rsrc_list_entry le;
le.ptr=ptr;
le.type=type;
le.refcount=1;
zval zv;
index = zend_hash_next_free_element(&EG(regular_list));
zend_hash_index_update(&EG(regular_list), index, (void *) &le, sizeof(zend_rsrc_list_entry), NULL);
return index;
ZVAL_NEW_RES(&zv, index, ptr, type);
return zend_hash_index_update(&EG(regular_list), index, &zv);
}
ZEND_API int _zend_list_delete(int id TSRMLS_DC)
ZEND_API int _zend_list_delete(zend_resource *res TSRMLS_DC)
{
zend_rsrc_list_entry *le;
if (zend_hash_index_find(&EG(regular_list), id, (void **) &le)==SUCCESS) {
/* printf("del(%d): %d->%d\n", id, le->refcount, le->refcount-1); */
if (--le->refcount<=0) {
return zend_hash_index_del(&EG(regular_list), id);
} else {
return SUCCESS;
}
if (res->gc.refcount <= 0) {
return zend_hash_index_del(&EG(regular_list), res->handle);
} else {
return FAILURE;
}
}
ZEND_API void *_zend_list_find(int id, int *type TSRMLS_DC)
{
zend_rsrc_list_entry *le;
if (zend_hash_index_find(&EG(regular_list), id, (void **) &le)==SUCCESS) {
*type = le->type;
return le->ptr;
} else {
*type = -1;
return NULL;
}
}
ZEND_API int _zend_list_addref(int id TSRMLS_DC)
{
zend_rsrc_list_entry *le;
if (zend_hash_index_find(&EG(regular_list), id, (void **) &le)==SUCCESS) {
/* printf("add(%d): %d->%d\n", id, le->refcount, le->refcount+1); */
le->refcount++;
return SUCCESS;
} else {
return FAILURE;
}
}
ZEND_API int zend_register_resource(zval *rsrc_result, void *rsrc_pointer, int rsrc_type TSRMLS_DC)
ZEND_API zend_resource* zend_register_resource(zval *rsrc_result, void *rsrc_pointer, int rsrc_type TSRMLS_DC)
{
int rsrc_id;
zval *zv;
rsrc_id = zend_list_insert(rsrc_pointer, rsrc_type TSRMLS_CC);
zv = zend_list_insert(rsrc_pointer, rsrc_type TSRMLS_CC);
if (rsrc_result) {
rsrc_result->value.lval = rsrc_id;
rsrc_result->type = IS_RESOURCE;
ZVAL_COPY_VALUE(rsrc_result, zv);
return Z_RES_P(rsrc_result);
} else {
return Z_RES_P(zv);
}
return rsrc_id;
}
ZEND_API void *zend_fetch_resource(zval **passed_id TSRMLS_DC, int default_id, const char *resource_type_name, int *found_resource_type, int num_resource_types, ...)
ZEND_API void *zend_fetch_resource(zval *passed_id TSRMLS_DC, int default_id, const char *resource_type_name, int *found_resource_type, int num_resource_types, ...)
{
int id;
int actual_resource_type;
void *resource;
// void *resource;
va_list resource_types;
int i;
zend_resource *res;
const char *space;
const char *class_name;
@ -123,26 +81,25 @@ ZEND_API void *zend_fetch_resource(zval **passed_id TSRMLS_DC, int default_id, c
zend_error(E_WARNING, "%s%s%s(): no %s resource supplied", class_name, space, get_active_function_name(TSRMLS_C), resource_type_name);
}
return NULL;
} else if ((*passed_id)->type != IS_RESOURCE) {
} else if (Z_TYPE_P(passed_id) != IS_RESOURCE) {
if (resource_type_name) {
class_name = get_active_class_name(&space TSRMLS_CC);
zend_error(E_WARNING, "%s%s%s(): supplied argument is not a valid %s resource", class_name, space, get_active_function_name(TSRMLS_C), resource_type_name);
}
return NULL;
}
id = (*passed_id)->value.lval;
} else {
id = default_id;
}
resource = zend_list_find(id, &actual_resource_type);
if (!resource) {
if (resource_type_name) {
class_name = get_active_class_name(&space TSRMLS_CC);
zend_error(E_WARNING, "%s%s%s(): %d is not a valid %s resource", class_name, space, get_active_function_name(TSRMLS_C), id, resource_type_name);
passed_id = zend_hash_index_find(&EG(regular_list), default_id);
if (!passed_id) {
if (resource_type_name) {
class_name = get_active_class_name(&space TSRMLS_CC);
zend_error(E_WARNING, "%s%s%s(): %d is not a valid %s resource", class_name, space, get_active_function_name(TSRMLS_C), default_id, resource_type_name);
}
return NULL;
}
return NULL;
}
res = Z_RES_P(passed_id);
actual_resource_type = res->type;
va_start(resource_types, num_resource_types);
for (i=0; i<num_resource_types; i++) {
@ -151,7 +108,7 @@ ZEND_API void *zend_fetch_resource(zval **passed_id TSRMLS_DC, int default_id, c
if (found_resource_type) {
*found_resource_type = actual_resource_type;
}
return resource;
return res->ptr;
}
}
va_end(resource_types);
@ -164,59 +121,58 @@ ZEND_API void *zend_fetch_resource(zval **passed_id TSRMLS_DC, int default_id, c
return NULL;
}
void list_entry_destructor(void *ptr)
void list_entry_destructor(zval *zv)
{
zend_rsrc_list_entry *le = (zend_rsrc_list_entry *) ptr;
zend_resource *res = Z_RES_P(zv);
zend_rsrc_list_dtors_entry *ld;
TSRMLS_FETCH();
if (zend_hash_index_find(&list_destructors, le->type, (void **) &ld)==SUCCESS) {
ld = zend_hash_index_find_ptr(&list_destructors, res->type);
if (ld) {
switch (ld->type) {
case ZEND_RESOURCE_LIST_TYPE_STD:
if (ld->list_dtor) {
(ld->list_dtor)(le->ptr);
(ld->list_dtor)(res->ptr);
}
break;
case ZEND_RESOURCE_LIST_TYPE_EX:
if (ld->list_dtor_ex) {
ld->list_dtor_ex(le TSRMLS_CC);
ld->list_dtor_ex(res->ptr TSRMLS_CC);
}
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
} else {
zend_error(E_WARNING,"Unknown list entry type in request shutdown (%d)", le->type);
zend_error(E_WARNING,"Unknown list entry type in request shutdown (%d)", res->type);
}
}
void plist_entry_destructor(void *ptr)
void plist_entry_destructor(zval *zv)
{
zend_rsrc_list_entry *le = (zend_rsrc_list_entry *) ptr;
zend_resource *res = Z_RES_P(zv);
zend_rsrc_list_dtors_entry *ld;
TSRMLS_FETCH();
if (zend_hash_index_find(&list_destructors, le->type, (void **) &ld)==SUCCESS) {
ld = zend_hash_index_find_ptr(&list_destructors, res->type);
if (ld) {
switch (ld->type) {
case ZEND_RESOURCE_LIST_TYPE_STD:
if (ld->plist_dtor) {
(ld->plist_dtor)(le->ptr);
(ld->plist_dtor)(res->ptr);
}
break;
case ZEND_RESOURCE_LIST_TYPE_EX:
if (ld->plist_dtor_ex) {
ld->plist_dtor_ex(le TSRMLS_CC);
ld->plist_dtor_ex(res TSRMLS_CC);
}
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
} else {
zend_error(E_WARNING,"Unknown persistent list entry type in module shutdown (%d)", le->type);
zend_error(E_WARNING,"Unknown persistent list entry type in module shutdown (%d)", res->type);
}
}
int zend_init_rsrc_list(TSRMLS_D)
{
if (zend_hash_init(&EG(regular_list), 0, NULL, list_entry_destructor, 0)==SUCCESS) {
@ -239,9 +195,9 @@ void zend_destroy_rsrc_list(HashTable *ht TSRMLS_DC)
zend_hash_graceful_reverse_destroy(ht);
}
static int clean_module_resource(zend_rsrc_list_entry *le, int *resource_id TSRMLS_DC)
static int clean_module_resource(zval *zv, int *resource_id TSRMLS_DC)
{
if (le->type == *resource_id) {
if (Z_RES_TYPE_P(zv) == *resource_id) {
return 1;
} else {
return 0;
@ -249,8 +205,9 @@ static int clean_module_resource(zend_rsrc_list_entry *le, int *resource_id TSRM
}
static int zend_clean_module_rsrc_dtors_cb(zend_rsrc_list_dtors_entry *ld, int *module_number TSRMLS_DC)
static int zend_clean_module_rsrc_dtors_cb(zval *zv, int *module_number TSRMLS_DC)
{
zend_rsrc_list_dtors_entry *ld = Z_PTR_P(zv);
if (ld->module_number == *module_number) {
zend_hash_apply_with_argument(&EG(persistent_list), (apply_func_arg_t) clean_module_resource, (void *) &(ld->resource_id) TSRMLS_CC);
return 1;
@ -268,21 +225,20 @@ void zend_clean_module_rsrc_dtors(int module_number TSRMLS_DC)
ZEND_API int zend_register_list_destructors(void (*ld)(void *), void (*pld)(void *), int module_number)
{
zend_rsrc_list_dtors_entry lde;
zend_rsrc_list_dtors_entry *lde;
zval zv;
#if 0
printf("Registering destructors %d for module %d\n", list_destructors.nNextFreeElement, module_number);
#endif
lde = emalloc(sizeof(zend_rsrc_list_dtors_entry));
lde->list_dtor=(void (*)(void *)) ld;
lde->plist_dtor=(void (*)(void *)) pld;
lde->list_dtor_ex = lde->plist_dtor_ex = NULL;
lde->module_number = module_number;
lde->resource_id = list_destructors.nNextFreeElement;
lde->type = ZEND_RESOURCE_LIST_TYPE_STD;
lde->type_name = NULL;
ZVAL_PTR(&zv, lde);
lde.list_dtor=(void (*)(void *)) ld;
lde.plist_dtor=(void (*)(void *)) pld;
lde.list_dtor_ex = lde.plist_dtor_ex = NULL;
lde.module_number = module_number;
lde.resource_id = list_destructors.nNextFreeElement;
lde.type = ZEND_RESOURCE_LIST_TYPE_STD;
lde.type_name = NULL;
if (zend_hash_next_index_insert(&list_destructors, (void *) &lde, sizeof(zend_rsrc_list_dtors_entry), NULL)==FAILURE) {
if (zend_hash_next_index_insert(&list_destructors, &zv) == NULL) {
return FAILURE;
}
return list_destructors.nNextFreeElement-1;
@ -291,38 +247,34 @@ ZEND_API int zend_register_list_destructors(void (*ld)(void *), void (*pld)(void
ZEND_API int zend_register_list_destructors_ex(rsrc_dtor_func_t ld, rsrc_dtor_func_t pld, const char *type_name, int module_number)
{
zend_rsrc_list_dtors_entry lde;
zend_rsrc_list_dtors_entry *lde;
zval zv;
#if 0
printf("Registering destructors %d for module %d\n", list_destructors.nNextFreeElement, module_number);
#endif
lde.list_dtor = NULL;
lde.plist_dtor = NULL;
lde.list_dtor_ex = ld;
lde.plist_dtor_ex = pld;
lde.module_number = module_number;
lde.resource_id = list_destructors.nNextFreeElement;
lde.type = ZEND_RESOURCE_LIST_TYPE_EX;
lde.type_name = type_name;
lde = emalloc(sizeof(zend_rsrc_list_dtors_entry));
lde->list_dtor = NULL;
lde->plist_dtor = NULL;
lde->list_dtor_ex = ld;
lde->plist_dtor_ex = pld;
lde->module_number = module_number;
lde->resource_id = list_destructors.nNextFreeElement;
lde->type = ZEND_RESOURCE_LIST_TYPE_EX;
lde->type_name = type_name;
ZVAL_PTR(&zv, lde);
if (zend_hash_next_index_insert(&list_destructors, (void *) &lde, sizeof(zend_rsrc_list_dtors_entry), NULL)==FAILURE) {
if (zend_hash_next_index_insert(&list_destructors, &zv) == NULL) {
return FAILURE;
}
return list_destructors.nNextFreeElement-1;
}
ZEND_API int zend_fetch_list_dtor_id(char *type_name)
ZEND_API int zend_fetch_list_dtor_id(const char *type_name)
{
zend_rsrc_list_dtors_entry *lde;
HashPosition pos;
zend_hash_internal_pointer_reset_ex(&list_destructors, &pos);
while (zend_hash_get_current_data_ex(&list_destructors, (void **)&lde, &pos) == SUCCESS) {
while ((lde = zend_hash_get_current_data_ptr_ex(&list_destructors, &pos)) != NULL) {
if (lde->type_name && (strcmp(type_name, lde->type_name) == 0)) {
#if 0
printf("Found resource id %d for resource type %s\n", (*lde).resource_id, type_name);
#endif
return lde->resource_id;
}
zend_hash_move_forward_ex(&list_destructors, &pos);
@ -348,15 +300,12 @@ void zend_destroy_rsrc_list_dtors(void)
}
const char *zend_rsrc_list_get_rsrc_type(int resource TSRMLS_DC)
const char *zend_rsrc_list_get_rsrc_type(zend_resource *res TSRMLS_DC)
{
zend_rsrc_list_dtors_entry *lde;
int rsrc_type;
if (!zend_list_find(resource, &rsrc_type))
return NULL;
if (zend_hash_index_find(&list_destructors, rsrc_type, (void **) &lde)==SUCCESS) {
lde = zend_hash_index_find_ptr(&list_destructors, res->type);
if (lde) {
return lde->type_name;
} else {
return NULL;

View file

@ -30,14 +30,14 @@ BEGIN_EXTERN_C()
#define ZEND_RESOURCE_LIST_TYPE_STD 1
#define ZEND_RESOURCE_LIST_TYPE_EX 2
typedef struct _zend_rsrc_list_entry {
void *ptr;
int type;
int refcount;
} zend_rsrc_list_entry;
//???typedef struct _zend_rsrc_list_entry {
//??? void *ptr;
//??? int type;
//??? int refcount;
//???} zend_rsrc_list_entry;
typedef void (*rsrc_dtor_func_t)(zend_rsrc_list_entry *rsrc TSRMLS_DC);
#define ZEND_RSRC_DTOR_FUNC(name) void name(zend_rsrc_list_entry *rsrc TSRMLS_DC)
typedef void (*rsrc_dtor_func_t)(zend_resource *res TSRMLS_DC);
#define ZEND_RSRC_DTOR_FUNC(name) void name(zend_resource *res TSRMLS_DC)
typedef struct _zend_rsrc_list_dtors_entry {
/* old style destructors */
@ -60,8 +60,8 @@ typedef struct _zend_rsrc_list_dtors_entry {
ZEND_API int zend_register_list_destructors(void (*ld)(void *), void (*pld)(void *), int module_number);
ZEND_API int zend_register_list_destructors_ex(rsrc_dtor_func_t ld, rsrc_dtor_func_t pld, const char *type_name, int module_number);
void list_entry_destructor(void *ptr);
void plist_entry_destructor(void *ptr);
void list_entry_destructor(zval *ptr);
void plist_entry_destructor(zval *ptr);
void zend_clean_module_rsrc_dtors(int module_number TSRMLS_DC);
int zend_init_rsrc_list(TSRMLS_D);
@ -70,20 +70,16 @@ void zend_destroy_rsrc_list(HashTable *ht TSRMLS_DC);
int zend_init_rsrc_list_dtors(void);
void zend_destroy_rsrc_list_dtors(void);
ZEND_API int zend_list_insert(void *ptr, int type TSRMLS_DC);
ZEND_API int _zend_list_addref(int id TSRMLS_DC);
ZEND_API int _zend_list_delete(int id TSRMLS_DC);
ZEND_API void *_zend_list_find(int id, int *type TSRMLS_DC);
ZEND_API zval *zend_list_insert(void *ptr, int type TSRMLS_DC);
ZEND_API int _zend_list_delete(zend_resource *res TSRMLS_DC);
#define zend_list_addref(id) _zend_list_addref(id TSRMLS_CC)
#define zend_list_delete(id) _zend_list_delete(id TSRMLS_CC)
#define zend_list_find(id, type) _zend_list_find(id, type TSRMLS_CC)
#define zend_list_delete(res) _zend_list_delete(res TSRMLS_CC)
ZEND_API int zend_register_resource(zval *rsrc_result, void *rsrc_pointer, int rsrc_type TSRMLS_DC);
ZEND_API void *zend_fetch_resource(zval **passed_id TSRMLS_DC, int default_id, const char *resource_type_name, int *found_resource_type, int num_resource_types, ...);
ZEND_API zend_resource *zend_register_resource(zval *rsrc_result, void *rsrc_pointer, int rsrc_type TSRMLS_DC);
ZEND_API void *zend_fetch_resource(zval *passed_id TSRMLS_DC, int default_id, const char *resource_type_name, int *found_resource_type, int num_resource_types, ...);
ZEND_API const char *zend_rsrc_list_get_rsrc_type(int resource TSRMLS_DC);
ZEND_API int zend_fetch_list_dtor_id(char *type_name);
ZEND_API const char *zend_rsrc_list_get_rsrc_type(zend_resource *res TSRMLS_DC);
ZEND_API int zend_fetch_list_dtor_id(const char *type_name);
extern ZEND_API int le_index_ptr; /* list entry type for index pointers */

View file

@ -129,7 +129,7 @@ int module_registry_cleanup(zend_module_entry *module TSRMLS_DC);
int module_registry_request_startup(zend_module_entry *module TSRMLS_DC);
int module_registry_unload_temp(const zend_module_entry *module TSRMLS_DC);
#define ZEND_MODULE_DTOR (void (*)(void *)) module_destructor
#define ZEND_MODULE_DTOR (void (*)(zval *)) module_destructor
#endif
/*

File diff suppressed because it is too large Load diff

View file

@ -50,11 +50,11 @@ typedef void (*zend_object_write_dimension_t)(zval *object, zval *offset, zval *
/* Used to create pointer to the property of the object, for future direct r/w access */
typedef zval **(*zend_object_get_property_ptr_ptr_t)(zval *object, zval *member, int type, const struct _zend_literal *key TSRMLS_DC);
typedef zval *(*zend_object_get_property_ptr_ptr_t)(zval *object, zval *member, int type, const struct _zend_literal *key TSRMLS_DC);
/* Used to set object value. Can be used to override assignments and scalar
write ops (like ++, +=) on the object */
typedef void (*zend_object_set_t)(zval **object, zval *value TSRMLS_DC);
typedef void (*zend_object_set_t)(zval *object, zval *value TSRMLS_DC);
/* Used to get object value. Can be used when converting object value to
* one of the basic types and when using scalar ops (like ++, +=) on the object
@ -87,18 +87,20 @@ typedef HashTable *(*zend_object_get_debug_info_t)(zval *object, int *is_temp TS
/* args on stack! */
/* Andi - EX(fbc) (function being called) needs to be initialized already in the INIT fcall opcode so that the parameters can be parsed the right way. We need to add another callback for this.
*/
typedef int (*zend_object_call_method_t)(const char *method, INTERNAL_FUNCTION_PARAMETERS);
typedef union _zend_function *(*zend_object_get_method_t)(zval **object_ptr, char *method, int method_len, const struct _zend_literal *key TSRMLS_DC);
typedef int (*zend_object_call_method_t)(zend_string *method, INTERNAL_FUNCTION_PARAMETERS);
typedef union _zend_function *(*zend_object_get_method_t)(zval *object_ptr, zend_string *method, const struct _zend_literal *key TSRMLS_DC);
typedef union _zend_function *(*zend_object_get_constructor_t)(zval *object TSRMLS_DC);
/* Object maintenance/destruction */
typedef void (*zend_object_add_ref_t)(zval *object TSRMLS_DC);
typedef void (*zend_object_del_ref_t)(zval *object TSRMLS_DC);
typedef void (*zend_object_delete_obj_t)(zval *object TSRMLS_DC);
typedef zend_object_value (*zend_object_clone_obj_t)(zval *object TSRMLS_DC);
typedef void (*zend_object_dtor_obj_t)(zend_object *object TSRMLS_DC);
typedef void (*zend_object_free_obj_t)(zend_object *object TSRMLS_DC);
typedef zend_object* (*zend_object_clone_obj_t)(zval *object TSRMLS_DC);
typedef zend_class_entry *(*zend_object_get_class_entry_t)(const zval *object TSRMLS_DC);
typedef int (*zend_object_get_class_name_t)(const zval *object, const char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC);
typedef zend_string *(*zend_object_get_class_name_t)(const zval *object, int parent TSRMLS_DC);
typedef int (*zend_object_compare_t)(zval *object1, zval *object2 TSRMLS_DC);
typedef int (*zend_object_compare_zvals_t)(zval *resul, zval *op1, zval *op2 TSRMLS_DC);
@ -110,16 +112,16 @@ typedef int (*zend_object_cast_t)(zval *readobj, zval *retval, int type TSRMLS_D
* Returns FAILURE if the object does not have any sense of overloaded dimensions */
typedef int (*zend_object_count_elements_t)(zval *object, long *count TSRMLS_DC);
typedef int (*zend_object_get_closure_t)(zval *obj, zend_class_entry **ce_ptr, union _zend_function **fptr_ptr, zval **zobj_ptr TSRMLS_DC);
typedef int (*zend_object_get_closure_t)(zval *obj, zend_class_entry **ce_ptr, union _zend_function **fptr_ptr, zval *zobj_ptr TSRMLS_DC);
typedef HashTable *(*zend_object_get_gc_t)(zval *object, zval ***table, int *n TSRMLS_DC);
typedef HashTable *(*zend_object_get_gc_t)(zval *object, zval **table, int *n TSRMLS_DC);
typedef int (*zend_object_do_operation_t)(zend_uchar opcode, zval *result, zval *op1, zval *op2 TSRMLS_DC);
struct _zend_object_handlers {
/* general object functions */
zend_object_add_ref_t add_ref;
zend_object_del_ref_t del_ref;
zend_object_free_obj_t free_obj;
zend_object_dtor_obj_t dtor_obj;
zend_object_clone_obj_t clone_obj;
/* individual object functions */
zend_object_read_property_t read_property;
@ -155,9 +157,9 @@ extern ZEND_API zend_object_handlers std_object_handlers;
((fbc)->common.prototype ? (fbc)->common.prototype->common.scope : (fbc)->common.scope)
BEGIN_EXTERN_C()
ZEND_API union _zend_function *zend_std_get_static_method(zend_class_entry *ce, const char *function_name_strval, int function_name_strlen, const struct _zend_literal *key TSRMLS_DC);
ZEND_API zval **zend_std_get_static_property(zend_class_entry *ce, const char *property_name, int property_name_len, zend_bool silent, const struct _zend_literal *key TSRMLS_DC);
ZEND_API zend_bool zend_std_unset_static_property(zend_class_entry *ce, const char *property_name, int property_name_len, const struct _zend_literal *key TSRMLS_DC);
ZEND_API union _zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_string *function_name_strval, const struct _zend_literal *key TSRMLS_DC);
ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *property_name, zend_bool silent, const struct _zend_literal *key TSRMLS_DC);
ZEND_API zend_bool zend_std_unset_static_property(zend_class_entry *ce, zend_string *property_name, const struct _zend_literal *key TSRMLS_DC);
ZEND_API union _zend_function *zend_std_get_constructor(zval *object TSRMLS_DC);
ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce, zval *member, int silent TSRMLS_DC);
ZEND_API HashTable *zend_std_get_properties(zval *object TSRMLS_DC);
@ -170,11 +172,11 @@ ZEND_API void rebuild_object_properties(zend_object *zobj);
#define IS_ZEND_STD_OBJECT(z) (Z_TYPE(z) == IS_OBJECT && (Z_OBJ_HT((z))->get_class_entry != NULL))
#define HAS_CLASS_ENTRY(z) (Z_OBJ_HT(z)->get_class_entry != NULL)
ZEND_API int zend_check_private(union _zend_function *fbc, zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC);
ZEND_API int zend_check_private(union _zend_function *fbc, zend_class_entry *ce, zend_string *function_name TSRMLS_DC);
ZEND_API int zend_check_protected(zend_class_entry *ce, zend_class_entry *scope);
ZEND_API int zend_check_property_access(zend_object *zobj, const char *prop_info_name, int prop_info_name_len TSRMLS_DC);
ZEND_API int zend_check_property_access(zend_object *zobj, zend_string *prop_info_name TSRMLS_DC);
ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTION_PARAMETERS);
END_EXTERN_C()

View file

@ -28,14 +28,20 @@
ZEND_API void zend_object_std_init(zend_object *object, zend_class_entry *ce TSRMLS_DC)
{
object->gc.refcount = 1;
object->gc.u.v.type = IS_OBJECT;
object->gc.u.v.buffer = 0;
object->ce = ce;
object->properties = NULL;
object->properties_table = NULL;
object->guards = NULL;
memset(object->properties_table, 0, sizeof(zval) * ce->default_properties_count);
zend_objects_store_put(object);
}
ZEND_API void zend_object_std_dtor(zend_object *object TSRMLS_DC)
{
int i;
if (object->guards) {
zend_hash_destroy(object->guards);
FREE_HASHTABLE(object->guards);
@ -46,26 +52,19 @@ ZEND_API void zend_object_std_dtor(zend_object *object TSRMLS_DC)
if (object->properties_table) {
efree(object->properties_table);
}
} else if (object->properties_table) {
int i;
for (i = 0; i < object->ce->default_properties_count; i++) {
if (object->properties_table[i]) {
zval_ptr_dtor(&object->properties_table[i]);
}
}
efree(object->properties_table);
}
for (i = 0; i < object->ce->default_properties_count; i++) {
zval_ptr_dtor(&object->properties_table[i]);
}
}
ZEND_API void zend_objects_destroy_object(zend_object *object, zend_object_handle handle TSRMLS_DC)
ZEND_API void zend_objects_destroy_object(zend_object *object TSRMLS_DC)
{
zend_function *destructor = object ? object->ce->destructor : NULL;
if (destructor) {
zval *old_exception;
zval *obj;
zend_object_store_bucket *obj_bucket;
zend_object *old_exception;
zval obj;
if (destructor->op_array.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) {
if (destructor->op_array.fn_flags & ZEND_ACC_PRIVATE) {
@ -76,8 +75,8 @@ ZEND_API void zend_objects_destroy_object(zend_object *object, zend_object_handl
zend_error(EG(in_execution) ? E_ERROR : E_WARNING,
"Call to private %s::__destruct() from context '%s'%s",
ce->name,
EG(scope) ? EG(scope)->name : "",
ce->name->val,
EG(scope) ? EG(scope)->name->val : "",
EG(in_execution) ? "" : " during shutdown ignored");
return;
}
@ -89,23 +88,16 @@ ZEND_API void zend_objects_destroy_object(zend_object *object, zend_object_handl
zend_error(EG(in_execution) ? E_ERROR : E_WARNING,
"Call to protected %s::__destruct() from context '%s'%s",
ce->name,
EG(scope) ? EG(scope)->name : "",
ce->name->val,
EG(scope) ? EG(scope)->name->val : "",
EG(in_execution) ? "" : " during shutdown ignored");
return;
}
}
}
MAKE_STD_ZVAL(obj);
Z_TYPE_P(obj) = IS_OBJECT;
Z_OBJ_HANDLE_P(obj) = handle;
obj_bucket = &EG(objects_store).object_buckets[handle];
if (!obj_bucket->bucket.obj.handlers) {
obj_bucket->bucket.obj.handlers = &std_object_handlers;
}
Z_OBJ_HT_P(obj) = obj_bucket->bucket.obj.handlers;
zval_copy_ctor(obj);
ZVAL_OBJ(&obj, object);
Z_ADDREF(obj);
/* Make sure that destructors are protected from previously thrown exceptions.
* For example, if an exception was thrown in a function and when the function's
@ -113,7 +105,7 @@ ZEND_API void zend_objects_destroy_object(zend_object *object, zend_object_handl
*/
old_exception = NULL;
if (EG(exception)) {
if (Z_OBJ_HANDLE_P(EG(exception)) == handle) {
if (EG(exception) == object) {
zend_error(E_ERROR, "Attempt to destruct pending exception");
} else {
old_exception = EG(exception);
@ -132,69 +124,52 @@ ZEND_API void zend_objects_destroy_object(zend_object *object, zend_object_handl
}
}
ZEND_API void zend_objects_free_object_storage(zend_object *object TSRMLS_DC)
ZEND_API void zend_object_free(zend_object *object TSRMLS_DC)
{
zend_object_std_dtor(object TSRMLS_CC);
efree(object);
}
ZEND_API zend_object_value zend_objects_new(zend_object **object, zend_class_entry *class_type TSRMLS_DC)
ZEND_API zend_object *zend_objects_new(zend_class_entry *ce TSRMLS_DC)
{
zend_object_value retval;
zend_object *object = emalloc(sizeof(zend_object) + sizeof(zval) * (ce->default_properties_count - 1));
*object = emalloc(sizeof(zend_object));
(*object)->ce = class_type;
(*object)->properties = NULL;
(*object)->properties_table = NULL;
(*object)->guards = NULL;
retval.handle = zend_objects_store_put(*object, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) zend_objects_free_object_storage, NULL TSRMLS_CC);
retval.handlers = &std_object_handlers;
return retval;
zend_object_std_init(object, ce);
object->handlers = &std_object_handlers;
return object;
}
ZEND_API zend_object *zend_objects_get_address(const zval *zobject TSRMLS_DC)
{
return (zend_object *)zend_object_store_get_object(zobject TSRMLS_CC);
}
ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object_value new_obj_val, zend_object *old_object, zend_object_handle handle TSRMLS_DC)
ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *old_object TSRMLS_DC)
{
int i;
if (old_object->properties_table) {
if (!new_object->properties_table) {
new_object->properties_table = emalloc(sizeof(zval*) * old_object->ce->default_properties_count);
memset(new_object->properties_table, 0, sizeof(zval*) * old_object->ce->default_properties_count);
}
for (i = 0; i < old_object->ce->default_properties_count; i++) {
if (!new_object->properties) {
if (new_object->properties_table[i]) {
zval_ptr_dtor(&new_object->properties_table[i]);
}
}
if (!old_object->properties) {
new_object->properties_table[i] = old_object->properties_table[i];
if (new_object->properties_table[i]) {
Z_ADDREF_P(new_object->properties_table[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]);
//??? }
}
if (old_object->properties) {
if (!new_object->properties) {
ALLOC_HASHTABLE(new_object->properties);
zend_hash_init(new_object->properties, 0, NULL, ZVAL_PTR_DTOR, 0);
}
zend_hash_copy(new_object->properties, old_object->properties, (copy_ctor_func_t) zval_add_ref, (void *) NULL /* Not used anymore */, sizeof(zval *));
zend_hash_copy(new_object->properties, old_object->properties, zval_add_ref);
if (old_object->properties_table) {
HashPosition pos;
zval *prop;
zend_property_info *prop_info;
for (zend_hash_internal_pointer_reset_ex(&old_object->ce->properties_info, &pos);
zend_hash_get_current_data_ex(&old_object->ce->properties_info, (void**)&prop_info, &pos) == SUCCESS;
(prop_info = zend_hash_get_current_data_ptr_ex(&old_object->ce->properties_info, &pos)) != NULL;
zend_hash_move_forward_ex(&old_object->ce->properties_info, &pos)) {
if ((prop_info->flags & ZEND_ACC_STATIC) == 0) {
if (zend_hash_quick_find(new_object->properties, prop_info->name, prop_info->name_length+1, prop_info->h, (void**)&new_object->properties_table[prop_info->offset]) == FAILURE) {
new_object->properties_table[prop_info->offset] = NULL;
if ((prop = zend_hash_find_ptr(new_object->properties, prop_info->name)) != NULL) {
ZVAL_COPY(&new_object->properties_table[prop_info->offset], prop);
} else {
ZVAL_UNDEF(&new_object->properties_table[prop_info->offset]);
}
}
}
@ -202,34 +177,28 @@ ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object_va
}
if (old_object->ce->clone) {
zval *new_obj;
MAKE_STD_ZVAL(new_obj);
new_obj->type = IS_OBJECT;
new_obj->value.obj = new_obj_val;
zval_copy_ctor(new_obj);
zval new_obj;
ZVAL_OBJ(&new_obj, new_object);
zval_copy_ctor(&new_obj);
zend_call_method_with_0_params(&new_obj, old_object->ce, &old_object->ce->clone, ZEND_CLONE_FUNC_NAME, NULL);
zval_ptr_dtor(&new_obj);
}
}
ZEND_API zend_object_value zend_objects_clone_obj(zval *zobject TSRMLS_DC)
ZEND_API zend_object *zend_objects_clone_obj(zval *zobject TSRMLS_DC)
{
zend_object_value new_obj_val;
zend_object *old_object;
zend_object *new_object;
zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
/* assume that create isn't overwritten, so when clone depends on the
* overwritten one then it must itself be overwritten */
old_object = zend_objects_get_address(zobject TSRMLS_CC);
new_obj_val = zend_objects_new(&new_object, old_object->ce TSRMLS_CC);
old_object = Z_OBJ_P(zobject);
new_object = zend_objects_new(old_object->ce TSRMLS_CC);
zend_objects_clone_members(new_object, new_obj_val, old_object, handle TSRMLS_CC);
zend_objects_clone_members(new_object, old_object TSRMLS_CC);
return new_obj_val;
return new_object;
}
/*

View file

@ -27,12 +27,11 @@
BEGIN_EXTERN_C()
ZEND_API void zend_object_std_init(zend_object *object, zend_class_entry *ce TSRMLS_DC);
ZEND_API void zend_object_std_dtor(zend_object *object TSRMLS_DC);
ZEND_API zend_object_value zend_objects_new(zend_object **object, zend_class_entry *class_type TSRMLS_DC);
ZEND_API void zend_objects_destroy_object(zend_object *object, zend_object_handle handle TSRMLS_DC);
ZEND_API zend_object *zend_objects_get_address(const zval *object TSRMLS_DC);
ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object_value new_obj_val, zend_object *old_object, zend_object_handle handle TSRMLS_DC);
ZEND_API zend_object_value zend_objects_clone_obj(zval *object TSRMLS_DC);
ZEND_API void zend_objects_free_object_storage(zend_object *object TSRMLS_DC);
ZEND_API zend_object *zend_objects_new(zend_class_entry *ce TSRMLS_DC);
ZEND_API void zend_objects_destroy_object(zend_object *object TSRMLS_DC);
ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *old_object TSRMLS_DC);
ZEND_API zend_object *zend_objects_clone_obj(zval *object TSRMLS_DC);
ZEND_API void zend_object_free(zend_object *object TSRMLS_DC);
END_EXTERN_C()
#endif /* ZEND_OBJECTS_H */

View file

@ -25,15 +25,25 @@
#include "zend_API.h"
#include "zend_objects_API.h"
#define ZEND_DEBUG_OBJECTS 0
#define FREE_BUCKET 1
#define IS_VALID(o) (!(((zend_uintptr_t)(o)) & FREE_BUCKET))
#define GET_BUCKET_NUMBER(o) (((zend_uintptr_t)(o)) >> 1)
#define SET_BUCKET_NUMBER(o, n) do { \
(o) = (((zend_uintptr_t)(n)) << 1) | FREE_BUCKET); \
} while (0)
ZEND_API void zend_objects_store_init(zend_objects_store *objects, zend_uint init_size)
{
objects->object_buckets = (zend_object_store_bucket *) emalloc(init_size * sizeof(zend_object_store_bucket));
objects->object_buckets = (zend_object **) emalloc(init_size * sizeof(zend_object*));
objects->top = 1; /* Skip 0 so that handles are true */
objects->size = init_size;
objects->free_list_head = -1;
memset(&objects->object_buckets[0], 0, sizeof(zend_object_store_bucket));
memset(&objects->object_buckets[0], 0, sizeof(zend_object*));
}
ZEND_API void zend_objects_store_destroy(zend_objects_store *objects)
@ -47,21 +57,17 @@ ZEND_API void zend_objects_store_call_destructors(zend_objects_store *objects TS
zend_uint i = 1;
for (i = 1; i < objects->top ; i++) {
if (objects->object_buckets[i].valid) {
struct _store_object *obj = &objects->object_buckets[i].bucket.obj;
zend_object *obj = objects->object_buckets[i];
if (!objects->object_buckets[i].destructor_called) {
objects->object_buckets[i].destructor_called = 1;
if (obj->dtor && obj->object) {
obj->refcount++;
obj->dtor(obj->object, i TSRMLS_CC);
obj = &objects->object_buckets[i].bucket.obj;
obj->refcount--;
if (IS_VALID(obj)) {
if (!(obj->gc.u.v.flags & IS_OBJ_DESTRUCTOR_CALLED)) {
obj->gc.u.v.flags |= IS_OBJ_DESTRUCTOR_CALLED;
obj->gc.refcount++;
obj->handlers->dtor_obj(obj TSRMLS_CC);
obj->gc.refcount--;
if (obj->refcount == 0) {
/* in case gc_collect_cycle is triggered before free_storage */
GC_REMOVE_ZOBJ_FROM_BUFFER(obj);
}
if (obj->gc.refcount == 0) {
gc_remove_zval_from_buffer((zend_refcounted*)obj TSRMLS_CC);
}
}
}
@ -76,8 +82,10 @@ ZEND_API void zend_objects_store_mark_destructed(zend_objects_store *objects TSR
return;
}
for (i = 1; i < objects->top ; i++) {
if (objects->object_buckets[i].valid) {
objects->object_buckets[i].destructor_called = 1;
zend_object *obj = objects->object_buckets[i];
if (IS_VALID(obj)) {
obj->gc.u.v.flags |= IS_OBJ_DESTRUCTOR_CALLED;
}
}
}
@ -87,14 +95,13 @@ ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects
zend_uint i = 1;
for (i = 1; i < objects->top ; i++) {
if (objects->object_buckets[i].valid) {
struct _store_object *obj = &objects->object_buckets[i].bucket.obj;
zend_object *obj = objects->object_buckets[i];
GC_REMOVE_ZOBJ_FROM_BUFFER(obj);
objects->object_buckets[i].valid = 0;
if (obj->free_storage) {
obj->free_storage(obj->object TSRMLS_CC);
if (IS_VALID(obj)) {
gc_remove_zval_from_buffer((zend_refcounted*)obj TSRMLS_CC);
//??? objects->object_buckets[i].valid = 0;
if (obj->handlers->free_obj) {
obj->handlers->free_obj(obj TSRMLS_CC);
}
/* Not adding to free list as we are shutting down anyway */
}
@ -104,63 +111,22 @@ ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects
/* Store objects API */
ZEND_API zend_object_handle zend_objects_store_put(void *object, zend_objects_store_dtor_t dtor, zend_objects_free_object_storage_t free_storage, zend_objects_store_clone_t clone TSRMLS_DC)
ZEND_API void zend_objects_store_put(zend_object *object TSRMLS_DC)
{
zend_object_handle handle;
struct _store_object *obj;
int handle;
if (EG(objects_store).free_list_head != -1) {
handle = EG(objects_store).free_list_head;
EG(objects_store).free_list_head = EG(objects_store).object_buckets[handle].bucket.free_list.next;
EG(objects_store).free_list_head = GET_BUCKET_NUMBER(EG(objects_store).object_buckets[handle]);
} else {
if (EG(objects_store).top == EG(objects_store).size) {
EG(objects_store).size <<= 1;
EG(objects_store).object_buckets = (zend_object_store_bucket *) erealloc(EG(objects_store).object_buckets, EG(objects_store).size * sizeof(zend_object_store_bucket));
EG(objects_store).object_buckets = (zend_object **) erealloc(EG(objects_store).object_buckets, EG(objects_store).size * sizeof(zend_object*));
}
handle = EG(objects_store).top++;
}
obj = &EG(objects_store).object_buckets[handle].bucket.obj;
EG(objects_store).object_buckets[handle].destructor_called = 0;
EG(objects_store).object_buckets[handle].valid = 1;
EG(objects_store).object_buckets[handle].apply_count = 0;
obj->refcount = 1;
GC_OBJ_INIT(obj);
obj->object = object;
obj->dtor = dtor?dtor:(zend_objects_store_dtor_t)zend_objects_destroy_object;
obj->free_storage = free_storage;
obj->clone = clone;
obj->handlers = NULL;
#if ZEND_DEBUG_OBJECTS
fprintf(stderr, "Allocated object id #%d\n", handle);
#endif
return handle;
}
ZEND_API zend_uint zend_objects_store_get_refcount(zval *object TSRMLS_DC)
{
zend_object_handle handle = Z_OBJ_HANDLE_P(object);
return EG(objects_store).object_buckets[handle].bucket.obj.refcount;
}
ZEND_API void zend_objects_store_add_ref(zval *object TSRMLS_DC)
{
zend_object_handle handle = Z_OBJ_HANDLE_P(object);
EG(objects_store).object_buckets[handle].bucket.obj.refcount++;
#if ZEND_DEBUG_OBJECTS
fprintf(stderr, "Increased refcount of object id #%d\n", handle);
#endif
}
/*
* Add a reference to an objects store entry given the object handle.
*/
ZEND_API void zend_objects_store_add_ref_by_handle(zend_object_handle handle TSRMLS_DC)
{
EG(objects_store).object_buckets[handle].bucket.obj.refcount++;
object->handle = handle;
EG(objects_store).object_buckets[handle] = object;
}
#define ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST() \
@ -168,22 +134,11 @@ ZEND_API void zend_objects_store_add_ref_by_handle(zend_object_handle handle TSR
EG(objects_store).free_list_head = handle; \
EG(objects_store).object_buckets[handle].valid = 0;
ZEND_API void zend_objects_store_del_ref(zval *zobject TSRMLS_DC)
{
zend_object_handle handle;
handle = Z_OBJ_HANDLE_P(zobject);
Z_ADDREF_P(zobject);
zend_objects_store_del_ref_by_handle_ex(handle, Z_OBJ_HT_P(zobject) TSRMLS_CC);
Z_DELREF_P(zobject);
GC_ZOBJ_CHECK_POSSIBLE_ROOT(zobject);
}
/*
* Delete a reference to an objects store entry given the object handle.
*/
//???
#if 0
ZEND_API void zend_objects_store_del_ref_by_handle_ex(zend_object_handle handle, const zend_object_handlers *handlers TSRMLS_DC) /* {{{ */
{
struct _store_object *obj;
@ -220,7 +175,7 @@ ZEND_API void zend_objects_store_del_ref_by_handle_ex(zend_object_handle handle,
obj = &EG(objects_store).object_buckets[handle].bucket.obj;
if (obj->refcount == 1) {
GC_REMOVE_ZOBJ_FROM_BUFFER(obj);
//??? GC_REMOVE_ZOBJ_FROM_BUFFER(obj);
if (obj->free_storage) {
zend_try {
obj->free_storage(obj->object TSRMLS_CC);
@ -235,33 +190,29 @@ ZEND_API void zend_objects_store_del_ref_by_handle_ex(zend_object_handle handle,
obj->refcount--;
#if ZEND_DEBUG_OBJECTS
if (obj->refcount == 0) {
fprintf(stderr, "Deallocated object id #%d\n", handle);
} else {
fprintf(stderr, "Decreased refcount of object id #%d\n", handle);
}
#endif
if (failure) {
zend_bailout();
}
}
#endif
/* }}} */
ZEND_API zend_object_value zend_objects_store_clone_obj(zval *zobject TSRMLS_DC)
//???
#if 0
ZEND_API zend_object *zend_objects_store_clone_obj(zval *zobject TSRMLS_DC)
{
zend_object_value retval;
void *new_object;
struct _store_object *obj;
zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
zend_object *obj, *new_object;
//??? struct _store_object *obj;
//??? zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
obj = &EG(objects_store).object_buckets[handle].bucket.obj;
//??? obj = &EG(objects_store).object_buckets[handle].bucket.obj;
if (obj->clone == NULL) {
zend_error(E_CORE_ERROR, "Trying to clone uncloneable object of class %s", Z_OBJCE_P(zobject)->name);
}
//??? if (obj->clone == NULL) {
//??? zend_error(E_CORE_ERROR, "Trying to clone uncloneable object of class %s", Z_OBJCE_P(zobject)->name);
//??? }
obj->clone(obj->object, &new_object TSRMLS_CC);
obj = Z_OBJ_P(zobject);
new_object = obj->handlers->clone_obj(obj TSRMLS_CC);
obj = &EG(objects_store).object_buckets[handle].bucket.obj;
retval.handle = zend_objects_store_put(new_object, obj->dtor, obj->free_storage, obj->clone TSRMLS_CC);
@ -270,21 +221,7 @@ ZEND_API zend_object_value zend_objects_store_clone_obj(zval *zobject TSRMLS_DC)
return retval;
}
ZEND_API void *zend_object_store_get_object(const zval *zobject TSRMLS_DC)
{
zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
return EG(objects_store).object_buckets[handle].bucket.obj.object;
}
/*
* Retrieve an entry from the objects store given the object handle.
*/
ZEND_API void *zend_object_store_get_object_by_handle(zend_object_handle handle TSRMLS_DC)
{
return EG(objects_store).object_buckets[handle].bucket.obj.object;
}
#endif
/* zend_object_store_set_object:
* It is ONLY valid to call this function from within the constructor of an
@ -293,15 +230,19 @@ ZEND_API void *zend_object_store_get_object_by_handle(zend_object_handle handle
* from the constructor function. You MUST NOT use this function for any other
* weird games, or call it at any other time after the object is constructed.
* */
//???
#if 0
ZEND_API void zend_object_store_set_object(zval *zobject, void *object TSRMLS_DC)
{
zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
EG(objects_store).object_buckets[handle].bucket.obj.object = object;
}
#endif
/* Called when the ctor was terminated by an exception */
//???
#if 0
ZEND_API void zend_object_store_ctor_failed(zval *zobject TSRMLS_DC)
{
zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
@ -310,17 +251,18 @@ ZEND_API void zend_object_store_ctor_failed(zval *zobject TSRMLS_DC)
obj_bucket->bucket.obj.handlers = Z_OBJ_HT_P(zobject);;
obj_bucket->destructor_called = 1;
}
#endif
/* Proxy objects workings */
typedef struct _zend_proxy_object {
zval *object;
zval *property;
zend_object std;
zval object;
zval property;
} zend_proxy_object;
static zend_object_handlers zend_object_proxy_handlers;
ZEND_API void zend_objects_proxy_destroy(zend_object *object, zend_object_handle handle TSRMLS_DC)
ZEND_API void zend_objects_proxy_destroy(zend_object *object TSRMLS_DC)
{
}
@ -336,35 +278,34 @@ ZEND_API void zend_objects_proxy_clone(zend_proxy_object *object, zend_proxy_obj
*object_clone = emalloc(sizeof(zend_proxy_object));
(*object_clone)->object = object->object;
(*object_clone)->property = object->property;
zval_add_ref(&(*object_clone)->property);
zval_add_ref(&(*object_clone)->object);
Z_ADDREF_P(&(*object_clone)->property);
Z_ADDREF_P(&(*object_clone)->object);
}
ZEND_API zval *zend_object_create_proxy(zval *object, zval *member TSRMLS_DC)
ZEND_API zend_object *zend_object_create_proxy(zval *object, zval *member TSRMLS_DC)
{
zend_proxy_object *pobj = emalloc(sizeof(zend_proxy_object));
zval *retval;
zend_proxy_object *obj = emalloc(sizeof(zend_proxy_object));
pobj->object = object;
zval_add_ref(&pobj->object);
ALLOC_ZVAL(pobj->property);
INIT_PZVAL_COPY(pobj->property, member);
zval_copy_ctor(pobj->property);
obj->std.gc.refcount = 1;
obj->std.gc.u.v.type = IS_OBJECT;
obj->std.gc.u.v.buffer = 0;
obj->std.ce = NULL;
obj->std.properties = NULL;
obj->std.guards = NULL;
obj->std.handlers = &zend_object_proxy_handlers;
ZVAL_COPY(&obj->object, object);
ZVAL_DUP(&obj->property, member);
MAKE_STD_ZVAL(retval);
Z_TYPE_P(retval) = IS_OBJECT;
Z_OBJ_HANDLE_P(retval) = zend_objects_store_put(pobj, (zend_objects_store_dtor_t)zend_objects_proxy_destroy, (zend_objects_free_object_storage_t) zend_objects_proxy_free_storage, (zend_objects_store_clone_t) zend_objects_proxy_clone TSRMLS_CC);
Z_OBJ_HT_P(retval) = &zend_object_proxy_handlers;
return retval;
return (zend_object*)obj;
}
ZEND_API void zend_object_proxy_set(zval **property, zval *value TSRMLS_DC)
ZEND_API void zend_object_proxy_set(zval *property, zval *value TSRMLS_DC)
{
zend_proxy_object *probj = zend_object_store_get_object(*property TSRMLS_CC);
zend_proxy_object *probj = (zend_proxy_object*)Z_OBJ_P(property);
if (Z_OBJ_HT_P(probj->object) && Z_OBJ_HT_P(probj->object)->write_property) {
Z_OBJ_HT_P(probj->object)->write_property(probj->object, probj->property, value, 0 TSRMLS_CC);
if (Z_OBJ_HT(probj->object) && Z_OBJ_HT(probj->object)->write_property) {
Z_OBJ_HT(probj->object)->write_property(&probj->object, &probj->property, value, 0 TSRMLS_CC);
} else {
zend_error(E_WARNING, "Cannot write property of object - no write handler defined");
}
@ -372,10 +313,10 @@ ZEND_API void zend_object_proxy_set(zval **property, zval *value TSRMLS_DC)
ZEND_API zval* zend_object_proxy_get(zval *property TSRMLS_DC)
{
zend_proxy_object *probj = zend_object_store_get_object(property TSRMLS_CC);
zend_proxy_object *probj = (zend_proxy_object*)Z_OBJ_P(property);
if (Z_OBJ_HT_P(probj->object) && Z_OBJ_HT_P(probj->object)->read_property) {
return Z_OBJ_HT_P(probj->object)->read_property(probj->object, probj->property, BP_VAR_R, 0 TSRMLS_CC);
if (Z_OBJ_HT(probj->object) && Z_OBJ_HT(probj->object)->read_property) {
return Z_OBJ_HT(probj->object)->read_property(&probj->object, &probj->property, BP_VAR_R, 0 TSRMLS_CC);
} else {
zend_error(E_WARNING, "Cannot read property of object - no read handler defined");
}

View file

@ -24,32 +24,35 @@
#include "zend.h"
typedef void (*zend_objects_store_dtor_t)(void *object, zend_object_handle handle TSRMLS_DC);
typedef void (*zend_objects_free_object_storage_t)(void *object TSRMLS_DC);
typedef void (*zend_objects_store_clone_t)(void *object, void **object_clone TSRMLS_DC);
//???typedef void (*zend_objects_store_dtor_t)(zend_object *object TSRMLS_DC);
//???typedef void (*zend_objects_free_object_storage_t)(void *object TSRMLS_DC);
//???typedef void (*zend_objects_store_clone_t)(zend_object *object, zend_object **object_clone TSRMLS_DC);
typedef struct _zend_object_store_bucket {
zend_bool destructor_called;
zend_bool valid;
zend_uchar apply_count;
union _store_bucket {
struct _store_object {
void *object;
zend_objects_store_dtor_t dtor;
zend_objects_free_object_storage_t free_storage;
zend_objects_store_clone_t clone;
const zend_object_handlers *handlers;
zend_uint refcount;
gc_root_buffer *buffered;
} obj;
struct {
int next;
} free_list;
} bucket;
} zend_object_store_bucket;
//???typedef union _zend_object_store_bucket {
//??? zend_object *object;
//??? int next_free;
//??? zend_bool destructor_called;
//??? zend_bool valid;
//??? zend_uchar apply_count;
//??? union _store_bucket {
//??? struct _store_object {
//??? zend_object *object;
//??? zend_objects_store_dtor_t dtor;
//??? zend_objects_free_object_storage_t free_storage;
//??? zend_objects_store_clone_t clone;
//??? const zend_object_handlers *handlers;
//??? zend_uint refcount;
//??? gc_root_buffer *buffered;
//??? } obj;
//??? zend_object *obj;
//??? struct {
//??? int next;
//??? } free_list;
//??? } bucket;
//???} zend_object_store_bucket;
typedef struct _zend_objects_store {
zend_object_store_bucket *object_buckets;
zend_object **object_buckets;
zend_uint top;
zend_uint size;
int free_list_head;
@ -63,28 +66,28 @@ ZEND_API void zend_objects_store_mark_destructed(zend_objects_store *objects TSR
ZEND_API void zend_objects_store_destroy(zend_objects_store *objects);
/* Store API functions */
ZEND_API zend_object_handle zend_objects_store_put(void *object, zend_objects_store_dtor_t dtor, zend_objects_free_object_storage_t storage, zend_objects_store_clone_t clone TSRMLS_DC);
ZEND_API void zend_objects_store_put(zend_object *object TSRMLS_DC);
ZEND_API void zend_objects_store_add_ref(zval *object TSRMLS_DC);
ZEND_API void zend_objects_store_del_ref(zval *object TSRMLS_DC);
ZEND_API void zend_objects_store_add_ref_by_handle(zend_object_handle handle TSRMLS_DC);
ZEND_API void zend_objects_store_del_ref_by_handle_ex(zend_object_handle handle, const zend_object_handlers *handlers TSRMLS_DC);
static zend_always_inline void zend_objects_store_del_ref_by_handle(zend_object_handle handle TSRMLS_DC) {
zend_objects_store_del_ref_by_handle_ex(handle, NULL TSRMLS_CC);
}
ZEND_API zend_uint zend_objects_store_get_refcount(zval *object TSRMLS_DC);
ZEND_API zend_object_value zend_objects_store_clone_obj(zval *object TSRMLS_DC);
ZEND_API void *zend_object_store_get_object(const zval *object TSRMLS_DC);
ZEND_API void *zend_object_store_get_object_by_handle(zend_object_handle handle TSRMLS_DC);
//???ZEND_API void zend_objects_store_add_ref(zval *object TSRMLS_DC);
//???ZEND_API void zend_objects_store_del_ref(zval *object TSRMLS_DC);
//???ZEND_API void zend_objects_store_add_ref_by_handle(zend_object_handle handle TSRMLS_DC);
//???ZEND_API void zend_objects_store_del_ref_by_handle_ex(zend_object_handle handle, const zend_object_handlers *handlers TSRMLS_DC);
//???static zend_always_inline void zend_objects_store_del_ref_by_handle(zend_object_handle handle TSRMLS_DC) {
//??? zend_objects_store_del_ref_by_handle_ex(handle, NULL TSRMLS_CC);
//???}
//???ZEND_API zend_uint zend_objects_store_get_refcount(zval *object TSRMLS_DC);
//???ZEND_API zend_object *zend_objects_store_clone_obj(zval *object TSRMLS_DC);
//???ZEND_API void *zend_object_store_get_object(const zval *object TSRMLS_DC);
//???ZEND_API void *zend_object_store_get_object_by_handle(zend_object_handle handle TSRMLS_DC);
/* See comment in zend_objects_API.c before you use this */
ZEND_API void zend_object_store_set_object(zval *zobject, void *object TSRMLS_DC);
//???ZEND_API void zend_object_store_set_object(zval *zobject, void *object TSRMLS_DC);
ZEND_API void zend_object_store_ctor_failed(zval *zobject TSRMLS_DC);
ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects TSRMLS_DC);
#define ZEND_OBJECTS_STORE_HANDLERS zend_objects_store_add_ref, zend_objects_store_del_ref, zend_objects_store_clone_obj
#define ZEND_OBJECTS_STORE_HANDLERS zend_object_free, zend_object_std_dtor, zend_objects_clone_obj
ZEND_API zval *zend_object_create_proxy(zval *object, zval *member TSRMLS_DC);
ZEND_API zend_object *zend_object_create_proxy(zval *object, zval *member TSRMLS_DC);
ZEND_API zend_object_handlers *zend_get_std_object_handlers(void);
END_EXTERN_C()

View file

@ -76,7 +76,6 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz
op_array->function_name = NULL;
op_array->filename = zend_get_compiled_filename(TSRMLS_C);
op_array->doc_comment = NULL;
op_array->doc_comment_len = 0;
op_array->arg_info = NULL;
op_array->num_args = 0;
@ -165,10 +164,12 @@ static inline void cleanup_user_class_data(zend_class_entry *ce TSRMLS_DC)
int i;
for (i = 0; i < ce->default_static_members_count; i++) {
if (ce->static_members_table[i]) {
zval *p = ce->static_members_table[i];
ce->static_members_table[i] = NULL;
zval_ptr_dtor(&p);
if (Z_TYPE(ce->static_members_table[i]) != IS_UNDEF) {
zval tmp;
ZVAL_COPY_VALUE(&tmp, &ce->static_members_table[i]);
ZVAL_UNDEF(&ce->static_members_table[i]);
zval_ptr_dtor(&tmp);
}
}
ce->static_members_table = NULL;
@ -279,7 +280,7 @@ ZEND_API void destroy_zend_class(zend_class_entry **pce)
int i;
for (i = 0; i < ce->default_properties_count; i++) {
if (ce->default_properties_table[i]) {
if (Z_TYPE(ce->default_properties_table[i]) != IS_UNDEF) {
zval_ptr_dtor(&ce->default_properties_table[i]);
}
}
@ -289,14 +290,14 @@ ZEND_API void destroy_zend_class(zend_class_entry **pce)
int i;
for (i = 0; i < ce->default_static_members_count; i++) {
if (ce->default_static_members_table[i]) {
if (Z_TYPE(ce->default_static_members_table[i]) != IS_UNDEF) {
zval_ptr_dtor(&ce->default_static_members_table[i]);
}
}
efree(ce->default_static_members_table);
}
zend_hash_destroy(&ce->properties_info);
str_efree(ce->name);
STR_RELEASE(ce->name);
zend_hash_destroy(&ce->function_table);
zend_hash_destroy(&ce->constants_table);
if (ce->num_interfaces > 0 && ce->interfaces) {
@ -315,7 +316,7 @@ ZEND_API void destroy_zend_class(zend_class_entry **pce)
int i;
for (i = 0; i < ce->default_properties_count; i++) {
if (ce->default_properties_table[i]) {
if (Z_TYPE(ce->default_properties_table[i]) != IS_UNDEF) {
zval_internal_ptr_dtor(&ce->default_properties_table[i]);
}
}
@ -330,7 +331,7 @@ ZEND_API void destroy_zend_class(zend_class_entry **pce)
free(ce->default_static_members_table);
}
zend_hash_destroy(&ce->properties_info);
str_free(ce->name);
STR_RELEASE(ce->name);
zend_hash_destroy(&ce->function_table);
zend_hash_destroy(&ce->constants_table);
if (ce->num_interfaces > 0) {
@ -371,7 +372,7 @@ ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC)
i = op_array->last_var;
while (i > 0) {
i--;
str_efree(op_array->vars[i].name);
STR_RELEASE(op_array->vars[i]);
}
efree(op_array->vars);
}
@ -403,9 +404,11 @@ ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC)
}
if (op_array->arg_info) {
for (i=0; i<op_array->num_args; i++) {
str_efree(op_array->arg_info[i].name);
//??? str_efree(op_array->arg_info[i].name);
efree((char*)op_array->arg_info[i].name);
if (op_array->arg_info[i].class_name) {
str_efree(op_array->arg_info[i].class_name);
//??? str_efree(op_array->arg_info[i].class_name);
efree((char*)op_array->arg_info[i].class_name);
}
}
efree(op_array->arg_info);
@ -671,7 +674,7 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
}
if (!(op_array->fn_flags & ZEND_ACC_INTERACTIVE) && CG(context).vars_size != op_array->last_var) {
op_array->vars = (zend_compiled_variable *) erealloc(op_array->vars, sizeof(zend_compiled_variable)*op_array->last_var);
op_array->vars = (zend_string**) erealloc(op_array->vars, sizeof(zend_string*)*op_array->last_var);
CG(context).vars_size = op_array->last_var;
}
if (!(op_array->fn_flags & ZEND_ACC_INTERACTIVE) && CG(context).opcodes_size != op_array->last) {
@ -732,9 +735,9 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
int print_class(zend_class_entry *class_entry TSRMLS_DC)
{
printf("Class %s:\n", class_entry->name);
printf("Class %s:\n", class_entry->name->val);
zend_hash_apply(&class_entry->function_table, (apply_func_t) pass_two TSRMLS_CC);
printf("End of class %s.\n\n", class_entry->name);
printf("End of class %s.\n\n", class_entry->name->val);
return 0;
}

View file

@ -186,21 +186,24 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */
switch (Z_TYPE_P(op)) {
case IS_STRING:
{
char *strval;
zend_string *str;
strval = Z_STRVAL_P(op);
if ((Z_TYPE_P(op)=is_numeric_string(strval, Z_STRLEN_P(op), &Z_LVAL_P(op), &Z_DVAL_P(op), 1)) == 0) {
str = Z_STR_P(op);
if ((Z_TYPE_P(op)=is_numeric_string(str->val, str->len, &Z_LVAL_P(op), &Z_DVAL_P(op), 1)) == 0) {
ZVAL_LONG(op, 0);
}
str_efree(strval);
STR_RELEASE(str);
break;
}
case IS_BOOL:
Z_TYPE_P(op) = IS_LONG;
break;
case IS_RESOURCE:
zend_list_delete(Z_LVAL_P(op));
Z_TYPE_P(op) = IS_LONG;
{
long l = Z_RES_HANDLE_P(op);
zval_ptr_dtor(op);
ZVAL_LONG(op, l);
}
break;
case IS_OBJECT:
convert_to_long_base(op, 10);
@ -238,8 +241,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */
(op) = &(holder); \
break; \
case IS_OBJECT: \
(holder) = (*(op)); \
zval_copy_ctor(&(holder)); \
ZVAL_DUP(&(holder), op); \
convert_to_long_base(&(holder), 10); \
if (Z_TYPE(holder) == IS_LONG) { \
(op) = &(holder); \
@ -269,8 +271,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */
Z_LVAL(holder) = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0); \
break; \
case IS_OBJECT: \
(holder) = (*(op)); \
zval_copy_ctor(&(holder)); \
ZVAL_DUP(&(holder), (op)); \
convert_to_long_base(&(holder), 10); \
break; \
case IS_BOOL: \
@ -316,8 +317,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */
Z_LVAL(holder) = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0); \
break; \
case IS_OBJECT: \
(holder) = (*(op)); \
zval_copy_ctor(&(holder)); \
ZVAL_DUP(&(holder), (op)); \
convert_to_boolean(&(holder)); \
break; \
default: \
@ -336,7 +336,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */
zval dst; \
if (Z_OBJ_HT_P(op)->cast_object(op, &dst, ctype TSRMLS_CC) == FAILURE) { \
zend_error(E_RECOVERABLE_ERROR, \
"Object of class %s could not be converted to %s", Z_OBJCE_P(op)->name, \
"Object of class %s could not be converted to %s", Z_OBJCE_P(op)->name->val,\
zend_get_type_by_const(ctype)); \
} else { \
zval_dtor(op); \
@ -349,8 +349,7 @@ ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */
if (Z_TYPE_P(newop) != IS_OBJECT) { \
/* for safety - avoid loop */ \
zval_dtor(op); \
*op = *newop; \
FREE_ZVAL(newop); \
ZVAL_COPY_VALUE(op, newop); \
conv_func(op); \
} \
} \
@ -376,8 +375,9 @@ ZEND_API void convert_to_long_base(zval *op, int base) /* {{{ */
break;
case IS_RESOURCE: {
TSRMLS_FETCH();
zend_list_delete(Z_LVAL_P(op));
long l = Z_RES_HANDLE_P(op);
zval_ptr_dtor(op);
Z_LVAL_P(op) = l;
}
/* break missing intentionally */
case IS_BOOL:
@ -388,10 +388,10 @@ ZEND_API void convert_to_long_base(zval *op, int base) /* {{{ */
break;
case IS_STRING:
{
char *strval = Z_STRVAL_P(op);
zend_string *str = Z_STR_P(op);
Z_LVAL_P(op) = strtol(strval, NULL, base);
str_efree(strval);
Z_LVAL_P(op) = strtol(str->val, NULL, base);
STR_RELEASE(str);
}
break;
case IS_ARRAY:
@ -409,7 +409,7 @@ ZEND_API void convert_to_long_base(zval *op, int base) /* {{{ */
if (Z_TYPE_P(op) == IS_LONG) {
return;
}
zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name);
zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name->val);
zval_dtor(op);
ZVAL_LONG(op, retval);
@ -436,10 +436,11 @@ ZEND_API void convert_to_double(zval *op) /* {{{ */
break;
case IS_RESOURCE: {
TSRMLS_FETCH();
zend_list_delete(Z_LVAL_P(op));
double d = (double) Z_RES_HANDLE_P(op);
zval_ptr_dtor(op);
Z_DVAL_P(op) = d;
}
/* break missing intentionally */
break;
case IS_BOOL:
case IS_LONG:
Z_DVAL_P(op) = (double) Z_LVAL_P(op);
@ -448,10 +449,10 @@ ZEND_API void convert_to_double(zval *op) /* {{{ */
break;
case IS_STRING:
{
char *strval = Z_STRVAL_P(op);
zend_string *str = Z_STR_P(op);
Z_DVAL_P(op) = zend_strtod(strval, NULL);
str_efree(strval);
Z_DVAL_P(op) = zend_strtod(str->val, NULL);
STR_RELEASE(str);
}
break;
case IS_ARRAY:
@ -469,7 +470,7 @@ ZEND_API void convert_to_double(zval *op) /* {{{ */
if (Z_TYPE_P(op) == IS_DOUBLE) {
return;
}
zend_error(E_NOTICE, "Object of class %s could not be converted to double", Z_OBJCE_P(op)->name);
zend_error(E_NOTICE, "Object of class %s could not be converted to double", Z_OBJCE_P(op)->name->val);
zval_dtor(op);
ZVAL_DOUBLE(op, retval);
@ -489,17 +490,15 @@ ZEND_API void convert_to_null(zval *op) /* {{{ */
{
if (Z_TYPE_P(op) == IS_OBJECT) {
if (Z_OBJ_HT_P(op)->cast_object) {
zval *org;
zval org;
TSRMLS_FETCH();
ALLOC_ZVAL(org);
*org = *op;
if (Z_OBJ_HT_P(op)->cast_object(org, op, IS_NULL TSRMLS_CC) == SUCCESS) {
zval_dtor(org);
ZVAL_COPY_VALUE(&org, op);
if (Z_OBJ_HT_P(op)->cast_object(&org, op, IS_NULL TSRMLS_CC) == SUCCESS) {
zval_dtor(&org);
return;
}
*op = *org;
FREE_ZVAL(org);
ZVAL_COPY_VALUE(op, &org);
}
}
@ -520,10 +519,12 @@ ZEND_API void convert_to_boolean(zval *op) /* {{{ */
break;
case IS_RESOURCE: {
TSRMLS_FETCH();
long l = (Z_RES_HANDLE_P(op) ? 1 : 0);
zend_list_delete(Z_LVAL_P(op));
zval_ptr_dtor(op);
Z_LVAL_P(op) = l;
}
/* break missing intentionally */
break;
case IS_LONG:
Z_LVAL_P(op) = (Z_LVAL_P(op) ? 1 : 0);
break;
@ -532,15 +533,15 @@ ZEND_API void convert_to_boolean(zval *op) /* {{{ */
break;
case IS_STRING:
{
char *strval = Z_STRVAL_P(op);
zend_string *str = Z_STR_P(op);
if (Z_STRLEN_P(op) == 0
|| (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {
if (str->len == 0
|| (str->len == 1 && str->val[0] == '0')) {
Z_LVAL_P(op) = 0;
} else {
Z_LVAL_P(op) = 1;
}
str_efree(strval);
STR_RELEASE(str);
}
break;
case IS_ARRAY:
@ -579,7 +580,7 @@ ZEND_API void _convert_to_cstring(zval *op ZEND_FILE_LINE_DC) /* {{{ */
case IS_DOUBLE: {
TSRMLS_FETCH();
dval = Z_DVAL_P(op);
Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%.*H", (int) EG(precision), dval);
Z_STRLEN_P(op) = zend_spprintf((char**)&Z_STRVAL_P(op), 0, "%.*H", (int) EG(precision), dval);
/* %H already handles removing trailing zeros from the fractional part, yay */
break;
}
@ -597,45 +598,55 @@ ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{{ */
switch (Z_TYPE_P(op)) {
case IS_NULL:
Z_STRVAL_P(op) = STR_EMPTY_ALLOC();
Z_STRLEN_P(op) = 0;
Z_STR_P(op) = STR_EMPTY_ALLOC();
break;
case IS_STRING:
break;
case IS_BOOL:
if (Z_LVAL_P(op)) {
Z_STRVAL_P(op) = estrndup_rel("1", 1);
Z_STRLEN_P(op) = 1;
Z_STR_P(op) = STR_INIT("1", 1, 0);
} else {
Z_STRVAL_P(op) = STR_EMPTY_ALLOC();
Z_STRLEN_P(op) = 0;
Z_STR_P(op) = STR_EMPTY_ALLOC();
}
break;
case IS_RESOURCE: {
long tmp = Z_LVAL_P(op);
char *str;
int len;
TSRMLS_FETCH();
zend_list_delete(Z_LVAL_P(op));
Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "Resource id #%ld", tmp);
zval_ptr_dtor(op);
len = zend_spprintf(&str, 0, "Resource id #%ld", tmp);
Z_STR_P(op) = STR_INIT(str, len, 0);
efree(str);
break;
}
case IS_LONG:
case IS_LONG: {
char *str;
int len;
lval = Z_LVAL_P(op);
Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%ld", lval);
len = zend_spprintf(&str, 0, "%ld", lval);
Z_STR_P(op) = STR_INIT(str, len, 0);
efree(str);
break;
}
case IS_DOUBLE: {
char *str;
int len;
TSRMLS_FETCH();
dval = Z_DVAL_P(op);
Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%.*G", (int) EG(precision), dval);
len = zend_spprintf(&str, 0, "%.*G", (int) EG(precision), dval);
/* %G already handles removing trailing zeros from the fractional part, yay */
Z_STR_P(op) = STR_INIT(str, len, 0);
efree(str);
break;
}
case IS_ARRAY:
zend_error(E_NOTICE, "Array to string conversion");
zval_dtor(op);
Z_STRVAL_P(op) = estrndup_rel("Array", sizeof("Array")-1);
Z_STRLEN_P(op) = sizeof("Array")-1;
Z_STR_P(op) = STR_INIT("Array", sizeof("Array")-1, 0);
break;
case IS_OBJECT: {
TSRMLS_FETCH();
@ -646,10 +657,9 @@ ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{{ */
return;
}
zend_error(E_NOTICE, "Object of class %s to string conversion", Z_OBJCE_P(op)->name);
zend_error(E_NOTICE, "Object of class %s to string conversion", Z_OBJCE_P(op)->name->val);
zval_dtor(op);
Z_STRVAL_P(op) = estrndup_rel("Object", sizeof("Object")-1);
Z_STRLEN_P(op) = sizeof("Object")-1;
Z_STR_P(op) = STR_INIT("Object", sizeof("Object")-1, 0);
break;
}
default:
@ -663,22 +673,20 @@ ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{{ */
static void convert_scalar_to_array(zval *op, int type TSRMLS_DC) /* {{{ */
{
zval *entry;
zval entry;
ALLOC_ZVAL(entry);
*entry = *op;
INIT_PZVAL(entry);
ZVAL_COPY_VALUE(&entry, op);
switch (type) {
case IS_ARRAY:
ALLOC_HASHTABLE(Z_ARRVAL_P(op));
ZVAL_NEW_ARR(op);
zend_hash_init(Z_ARRVAL_P(op), 0, NULL, ZVAL_PTR_DTOR, 0);
zend_hash_index_update(Z_ARRVAL_P(op), 0, (void *) &entry, sizeof(zval *), NULL);
zend_hash_index_update(Z_ARRVAL_P(op), 0, &entry);
Z_TYPE_P(op) = IS_ARRAY;
break;
case IS_OBJECT:
object_init(op);
zend_hash_update(Z_OBJPROP_P(op), "scalar", sizeof("scalar"), (void *) &entry, sizeof(zval *), NULL);
zend_hash_str_update(Z_OBJPROP_P(op), "scalar", sizeof("scalar")-1, &entry);
break;
}
}
@ -694,41 +702,36 @@ ZEND_API void convert_to_array(zval *op) /* {{{ */
/* OBJECTS_OPTIMIZE */
case IS_OBJECT:
{
zval *tmp;
HashTable *ht;
zval arr;
ALLOC_HASHTABLE(ht);
zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0);
ZVAL_NEW_ARR(&arr);
zend_hash_init(Z_ARRVAL(arr), 0, NULL, ZVAL_PTR_DTOR, 0);
if (Z_OBJCE_P(op) == zend_ce_closure) {
convert_scalar_to_array(op, IS_ARRAY TSRMLS_CC);
if (Z_TYPE_P(op) == IS_ARRAY) {
zend_hash_destroy(ht);
FREE_HASHTABLE(ht);
zval_dtor(&arr);
return;
}
} else if (Z_OBJ_HT_P(op)->get_properties) {
HashTable *obj_ht = Z_OBJ_HT_P(op)->get_properties(op TSRMLS_CC);
if (obj_ht) {
zend_hash_copy(ht, obj_ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
zend_hash_copy(Z_ARRVAL(arr), obj_ht, zval_add_ref);
}
} else {
convert_object_to_type(op, IS_ARRAY, convert_to_array);
if (Z_TYPE_P(op) == IS_ARRAY) {
zend_hash_destroy(ht);
FREE_HASHTABLE(ht);
zval_dtor(&arr);
return;
}
}
zval_dtor(op);
Z_TYPE_P(op) = IS_ARRAY;
Z_ARRVAL_P(op) = ht;
ZVAL_COPY_VALUE(op, &arr);
}
break;
case IS_NULL:
ALLOC_HASHTABLE(Z_ARRVAL_P(op));
ZVAL_NEW_ARR(op);
zend_hash_init(Z_ARRVAL_P(op), 0, NULL, ZVAL_PTR_DTOR, 0);
Z_TYPE_P(op) = IS_ARRAY;
break;
default:
convert_scalar_to_array(op, IS_ARRAY TSRMLS_CC);
@ -761,13 +764,13 @@ ZEND_API void convert_to_object(zval *op) /* {{{ */
ZEND_API void multi_convert_to_long_ex(int argc, ...) /* {{{ */
{
zval **arg;
zval *arg;
va_list ap;
va_start(ap, argc);
while (argc--) {
arg = va_arg(ap, zval **);
arg = va_arg(ap, zval *);
convert_to_long_ex(arg);
}
@ -777,13 +780,13 @@ ZEND_API void multi_convert_to_long_ex(int argc, ...) /* {{{ */
ZEND_API void multi_convert_to_double_ex(int argc, ...) /* {{{ */
{
zval **arg;
zval *arg;
va_list ap;
va_start(ap, argc);
while (argc--) {
arg = va_arg(ap, zval **);
arg = va_arg(ap, zval *);
convert_to_double_ex(arg);
}
@ -793,13 +796,13 @@ ZEND_API void multi_convert_to_double_ex(int argc, ...) /* {{{ */
ZEND_API void multi_convert_to_string_ex(int argc, ...) /* {{{ */
{
zval **arg;
zval *arg;
va_list ap;
va_start(ap, argc);
while (argc--) {
arg = va_arg(ap, zval **);
arg = va_arg(ap, zval *);
convert_to_string_ex(arg);
}
@ -840,20 +843,16 @@ ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ *
ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
return SUCCESS;
case TYPE_PAIR(IS_ARRAY, IS_ARRAY): {
zval *tmp;
case TYPE_PAIR(IS_ARRAY, IS_ARRAY):
if ((result == op1) && (result == op2)) {
/* $a += $a */
return SUCCESS;
}
if (result != op1) {
*result = *op1;
zval_copy_ctor(result);
ZVAL_DUP(result, op1);
}
zend_hash_merge(Z_ARRVAL_P(result), Z_ARRVAL_P(op2), (void (*)(void *pData)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0);
zend_hash_merge(Z_ARRVAL_P(result), Z_ARRVAL_P(op2), zval_add_ref, 0);
return SUCCESS;
}
default:
if (!converted) {
@ -1112,8 +1111,7 @@ ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
zval op1_copy = *op1;
Z_TYPE_P(result) = IS_STRING;
Z_STRVAL_P(result) = estrndup(Z_STRVAL(op1_copy), Z_STRLEN(op1_copy));
Z_STRLEN_P(result) = Z_STRLEN(op1_copy);
Z_STR_P(result) = STR_DUP(Z_STR(op1_copy), 0);
for (i = 0; i < Z_STRLEN(op1_copy); i++) {
Z_STRVAL_P(result)[i] = ~Z_STRVAL(op1_copy)[i];
}
@ -1135,8 +1133,8 @@ ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /
if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
zval *longer, *shorter;
char *result_str;
int i, result_len;
zend_string *str;
int i;
if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
longer = op1;
@ -1146,17 +1144,14 @@ ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /
shorter = op1;
}
Z_TYPE_P(result) = IS_STRING;
result_len = Z_STRLEN_P(longer);
result_str = estrndup(Z_STRVAL_P(longer), Z_STRLEN_P(longer));
str = STR_DUP(Z_STR_P(longer), 0);
for (i = 0; i < Z_STRLEN_P(shorter); i++) {
result_str[i] |= Z_STRVAL_P(shorter)[i];
str->val[i] |= Z_STRVAL_P(shorter)[i];
}
if (result==op1) {
str_efree(Z_STRVAL_P(result));
STR_RELEASE(Z_STR_P(result));
}
Z_STRVAL_P(result) = result_str;
Z_STRLEN_P(result) = result_len;
ZVAL_STR(result, str);
return SUCCESS;
}
@ -1182,8 +1177,8 @@ ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
zval *longer, *shorter;
char *result_str;
int i, result_len;
zend_string *str;
int i;
if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
longer = op1;
@ -1193,17 +1188,14 @@ ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
shorter = op1;
}
Z_TYPE_P(result) = IS_STRING;
result_len = Z_STRLEN_P(shorter);
result_str = estrndup(Z_STRVAL_P(shorter), Z_STRLEN_P(shorter));
str = STR_DUP(Z_STR_P(shorter), 0);
for (i = 0; i < Z_STRLEN_P(shorter); i++) {
result_str[i] &= Z_STRVAL_P(longer)[i];
str->val[i] &= Z_STRVAL_P(longer)[i];
}
if (result==op1) {
str_efree(Z_STRVAL_P(result));
STR_RELEASE(Z_STR_P(result));
}
Z_STRVAL_P(result) = result_str;
Z_STRLEN_P(result) = result_len;
ZVAL_STR(result, str);
return SUCCESS;
}
@ -1229,8 +1221,8 @@ ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
zval *longer, *shorter;
char *result_str;
int i, result_len;
zend_string *str;
int i;
if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
longer = op1;
@ -1240,17 +1232,14 @@ ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
shorter = op1;
}
Z_TYPE_P(result) = IS_STRING;
result_len = Z_STRLEN_P(shorter);
result_str = estrndup(Z_STRVAL_P(shorter), Z_STRLEN_P(shorter));
str = STR_DUP(Z_STR_P(shorter), 0);
for (i = 0; i < Z_STRLEN_P(shorter); i++) {
result_str[i] ^= Z_STRVAL_P(longer)[i];
str->val[i] ^= Z_STRVAL_P(longer)[i];
}
if (result==op1) {
str_efree(Z_STRVAL_P(result));
STR_RELEASE(Z_STR_P(result));
}
Z_STRVAL_P(result) = result_str;
Z_STRLEN_P(result) = result_len;
ZVAL_STR(result, str);
return SUCCESS;
}
@ -1313,11 +1302,11 @@ ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */
{
int length = Z_STRLEN_P(op1) + 1;
char *buf = str_erealloc(Z_STRVAL_P(op1), length + 1);
zend_string *buf = STR_EREALLOC(Z_STR_P(op1), length + 1);
buf[length - 1] = (char) Z_LVAL_P(op2);
buf[length] = 0;
ZVAL_STRINGL(result, buf, length, 0);
buf->val[length - 1] = (char) Z_LVAL_P(op2);
buf->val[length] = 0;
ZVAL_STR(result, buf);
return SUCCESS;
}
/* }}} */
@ -1326,11 +1315,11 @@ ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2)
ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */
{
int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
char *buf = str_erealloc(Z_STRVAL_P(op1), length + 1);
zend_string *buf = STR_EREALLOC(Z_STR_P(op1), length + 1);
memcpy(buf + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
buf[length] = 0;
ZVAL_STRINGL(result, buf, length, 0);
memcpy(buf->val + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
buf->val[length] = 0;
ZVAL_STR(result, buf);
return SUCCESS;
}
/* }}} */
@ -1363,28 +1352,26 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{
if (use_copy2) {
op2 = &op2_copy;
}
if (result==op1 && !IS_INTERNED(Z_STRVAL_P(op1))) { /* special case, perform operations on result */
if (result==op1 && !IS_INTERNED(Z_STR_P(op1))) { /* special case, perform operations on result */
uint res_len = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
if (Z_STRLEN_P(result) < 0 || (int) (Z_STRLEN_P(op1) + Z_STRLEN_P(op2)) < 0) {
efree(Z_STRVAL_P(result));
ZVAL_EMPTY_STRING(result);
zend_error(E_ERROR, "String size overflow");
}
Z_STRVAL_P(result) = erealloc(Z_STRVAL_P(result), res_len+1);
Z_STR_P(result) = STR_EREALLOC(Z_STR_P(result), res_len+1);
memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(result), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
Z_STRVAL_P(result)[res_len]=0;
Z_STRLEN_P(result) = res_len;
} else {
int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
char *buf = (char *) emalloc(length + 1);
zend_string *buf = STR_ALLOC(length, 0);
memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1));
memcpy(buf + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
buf[length] = 0;
ZVAL_STRINGL(result, buf, length, 0);
memcpy(buf->val, Z_STRVAL_P(op1), Z_STRLEN_P(op1));
memcpy(buf->val + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
buf->val[length] = 0;
ZVAL_STR(result, buf);
}
if (use_copy1) {
zval_dtor(op1);
@ -1480,11 +1467,8 @@ ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_
{
zval op1_copy, op2_copy;
op1_copy = *op1;
zval_copy_ctor(&op1_copy);
op2_copy = *op2;
zval_copy_ctor(&op2_copy);
ZVAL_DUP(&op1_copy, op1);
ZVAL_DUP(&op2_copy, op2);
convert_to_double(&op1_copy);
convert_to_double(&op2_copy);
@ -1500,9 +1484,9 @@ static inline void zend_free_obj_get_result(zval *op TSRMLS_DC) /* {{{ */
if (Z_REFCOUNT_P(op) == 0) {
GC_REMOVE_ZVAL_FROM_BUFFER(op);
zval_dtor(op);
FREE_ZVAL(op);
//??? FREE_ZVAL(op);
} else {
zval_ptr_dtor(&op);
zval_ptr_dtor(op);
}
}
/* }}} */
@ -1512,7 +1496,7 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {
int ret;
int converted = 0;
zval op1_copy, op2_copy;
zval *op_free;
zval *op_free, tmp_free;
while (1) {
switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
@ -1587,7 +1571,7 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {
}
if (Z_TYPE_P(op1) == IS_OBJECT && Z_TYPE_P(op2) == IS_OBJECT) {
if (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2)) {
if (Z_OBJ_P(op1) == Z_OBJ_P(op2)) {
/* object handles are identical, apparently this is the same object */
ZVAL_LONG(result, 0);
return SUCCESS;
@ -1604,14 +1588,13 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {
zend_free_obj_get_result(op_free TSRMLS_CC);
return ret;
} else if (Z_TYPE_P(op2) != IS_OBJECT && Z_OBJ_HT_P(op1)->cast_object) {
ALLOC_INIT_ZVAL(op_free);
if (Z_OBJ_HT_P(op1)->cast_object(op1, op_free, Z_TYPE_P(op2) TSRMLS_CC) == FAILURE) {
if (Z_OBJ_HT_P(op1)->cast_object(op1, &tmp_free, Z_TYPE_P(op2) TSRMLS_CC) == FAILURE) {
ZVAL_LONG(result, 1);
zend_free_obj_get_result(op_free TSRMLS_CC);
zend_free_obj_get_result(&tmp_free TSRMLS_CC);
return SUCCESS;
}
ret = compare_function(result, op_free, op2 TSRMLS_CC);
zend_free_obj_get_result(op_free TSRMLS_CC);
ret = compare_function(result, &tmp_free, op2 TSRMLS_CC);
zend_free_obj_get_result(&tmp_free TSRMLS_CC);
return ret;
}
}
@ -1622,14 +1605,13 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {
zend_free_obj_get_result(op_free TSRMLS_CC);
return ret;
} else if (Z_TYPE_P(op1) != IS_OBJECT && Z_OBJ_HT_P(op2)->cast_object) {
ALLOC_INIT_ZVAL(op_free);
if (Z_OBJ_HT_P(op2)->cast_object(op2, op_free, Z_TYPE_P(op1) TSRMLS_CC) == FAILURE) {
if (Z_OBJ_HT_P(op2)->cast_object(op2, &tmp_free, Z_TYPE_P(op1) TSRMLS_CC) == FAILURE) {
ZVAL_LONG(result, -1);
zend_free_obj_get_result(op_free TSRMLS_CC);
zend_free_obj_get_result(&tmp_free TSRMLS_CC);
return SUCCESS;
}
ret = compare_function(result, op1, op_free TSRMLS_CC);
zend_free_obj_get_result(op_free TSRMLS_CC);
ret = compare_function(result, op1, &tmp_free TSRMLS_CC);
zend_free_obj_get_result(&tmp_free TSRMLS_CC);
return ret;
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
ZVAL_LONG(result, 1);
@ -1725,7 +1707,7 @@ ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
break;
case IS_OBJECT:
if (Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)) {
Z_LVAL_P(result) = (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2));
Z_LVAL_P(result) = (Z_OBJ_P(op1) == Z_OBJ_P(op2));
} else {
Z_LVAL_P(result) = 0;
}
@ -1824,21 +1806,24 @@ static void increment_string(zval *str) /* {{{ */
{
int carry=0;
int pos=Z_STRLEN_P(str)-1;
char *s=Z_STRVAL_P(str);
char *t;
char *s;
zend_string *t;
int last=0; /* Shut up the compiler warning */
int ch;
if (Z_STRLEN_P(str) == 0) {
str_efree(Z_STRVAL_P(str));
Z_STRVAL_P(str) = estrndup("1", sizeof("1")-1);
Z_STRLEN_P(str) = 1;
STR_RELEASE(Z_STR_P(str));
Z_STR_P(str) = STR_INIT("1", sizeof("1")-1, 0);
return;
}
if (IS_INTERNED(s)) {
Z_STRVAL_P(str) = s = estrndup(s, Z_STRLEN_P(str));
if (IS_INTERNED(Z_STR_P(str))) {
Z_STR_P(str) = STR_DUP(Z_STR_P(str), 0);
} else if (Z_REFCOUNT_P(str) > 1) {
Z_DELREF_P(str);
Z_STR_P(str) = STR_DUP(Z_STR_P(str), 0);
}
s = Z_STRVAL_P(str);
while (pos >= 0) {
ch = s[pos];
@ -1880,23 +1865,22 @@ static void increment_string(zval *str) /* {{{ */
}
if (carry) {
t = (char *) emalloc(Z_STRLEN_P(str)+1+1);
memcpy(t+1, Z_STRVAL_P(str), Z_STRLEN_P(str));
Z_STRLEN_P(str)++;
t[Z_STRLEN_P(str)] = '\0';
t = STR_ALLOC(Z_STRLEN_P(str)+1, 0);
memcpy(t->val + 1, Z_STRVAL_P(str), Z_STRLEN_P(str));
t->val[Z_STRLEN_P(str) + 1] = '\0';
switch (last) {
case NUMERIC:
t[0] = '1';
t->val[0] = '1';
break;
case UPPER_CASE:
t[0] = 'A';
t->val[0] = 'A';
break;
case LOWER_CASE:
t[0] = 'a';
t->val[0] = 'a';
break;
}
str_efree(Z_STRVAL_P(str));
Z_STRVAL_P(str) = t;
STR_FREE(Z_STR_P(str));
ZVAL_STR(str, t);
}
}
/* }}} */
@ -1925,7 +1909,7 @@ ZEND_API int increment_function(zval *op1) /* {{{ */
switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
case IS_LONG:
str_efree(Z_STRVAL_P(op1));
STR_RELEASE(Z_STR_P(op1));
if (lval == LONG_MAX) {
/* switch to double */
double d = (double)lval;
@ -1935,7 +1919,7 @@ ZEND_API int increment_function(zval *op1) /* {{{ */
}
break;
case IS_DOUBLE:
str_efree(Z_STRVAL_P(op1));
STR_RELEASE(Z_STR_P(op1));
ZVAL_DOUBLE(op1, dval+1);
break;
default:
@ -1947,13 +1931,12 @@ ZEND_API int increment_function(zval *op1) /* {{{ */
break;
case IS_OBJECT:
if (Z_OBJ_HANDLER_P(op1, do_operation)) {
zval *op2;
zval op2;
int res;
TSRMLS_FETCH();
MAKE_STD_ZVAL(op2);
ZVAL_LONG(op2, 1);
res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_ADD, op1, op1, op2 TSRMLS_CC);
ZVAL_LONG(&op2, 1);
res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_ADD, op1, op1, &op2 TSRMLS_CC);
zval_ptr_dtor(&op2);
return res;
@ -1985,13 +1968,13 @@ ZEND_API int decrement_function(zval *op1) /* {{{ */
break;
case IS_STRING: /* Like perl we only support string increment */
if (Z_STRLEN_P(op1) == 0) { /* consider as 0 */
str_efree(Z_STRVAL_P(op1));
STR_RELEASE(Z_STR_P(op1));
ZVAL_LONG(op1, -1);
break;
}
switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
case IS_LONG:
str_efree(Z_STRVAL_P(op1));
STR_RELEASE(Z_STR_P(op1));
if (lval == LONG_MIN) {
double d = (double)lval;
ZVAL_DOUBLE(op1, d-1);
@ -2000,20 +1983,19 @@ ZEND_API int decrement_function(zval *op1) /* {{{ */
}
break;
case IS_DOUBLE:
str_efree(Z_STRVAL_P(op1));
STR_RELEASE(Z_STR_P(op1));
ZVAL_DOUBLE(op1, dval - 1);
break;
}
break;
case IS_OBJECT:
if (Z_OBJ_HANDLER_P(op1, do_operation)) {
zval *op2;
zval op2;
int res;
TSRMLS_FETCH();
MAKE_STD_ZVAL(op2);
ZVAL_LONG(op2, 1);
res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_SUB, op1, op1, op2 TSRMLS_CC);
ZVAL_LONG(&op2, 1);
res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_SUB, op1, op1, &op2 TSRMLS_CC);
zval_ptr_dtor(&op2);
return res;
@ -2302,7 +2284,7 @@ ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC) /
{
Z_TYPE_P(result) = IS_LONG;
if (Z_OBJ_HANDLE_P(o1) == Z_OBJ_HANDLE_P(o2)) {
if (Z_OBJ_P(o1) == Z_OBJ_P(o2)) {
Z_LVAL_P(result) = 0;
return;
}
@ -2318,8 +2300,12 @@ ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC) /
ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC) /* {{{ */
{
TSRMLS_FETCH();
char *str;
int len;
Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%.*G", (int) EG(precision), (double)Z_DVAL_P(op));
len = zend_spprintf(&str, 0, "%.*G", (int) EG(precision), (double)Z_DVAL_P(op));
Z_STR_P(op) = STR_INIT(str, len, 0);
efree(str);
}
/* }}} */

View file

@ -378,10 +378,10 @@ ZEND_API long zend_atol(const char *str, int str_len);
ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC);
END_EXTERN_C()
#define convert_to_ex_master(ppzv, lower_type, upper_type) \
if (Z_TYPE_PP(ppzv)!=IS_##upper_type) { \
SEPARATE_ZVAL_IF_NOT_REF(ppzv); \
convert_to_##lower_type(*ppzv); \
#define convert_to_ex_master(pzv, lower_type, upper_type) \
if (Z_TYPE_P(pzv)!=IS_##upper_type) { \
SEPARATE_ZVAL_IF_NOT_REF(pzv); \
convert_to_##lower_type(pzv); \
}
#define convert_to_explicit_type(pzv, type) \
@ -414,81 +414,28 @@ END_EXTERN_C()
} \
} while (0);
#define convert_to_explicit_type_ex(ppzv, str_type) \
if (Z_TYPE_PP(ppzv) != str_type) { \
SEPARATE_ZVAL_IF_NOT_REF(ppzv); \
convert_to_explicit_type(*ppzv, str_type); \
#define convert_to_explicit_type_ex(pzv, str_type) \
if (Z_TYPE_P(pzv) != str_type) { \
SEPARATE_ZVAL_IF_NOT_REF(pzv); \
convert_to_explicit_type(pzv, str_type); \
}
#define convert_to_boolean_ex(ppzv) convert_to_ex_master(ppzv, boolean, BOOL)
#define convert_to_long_ex(ppzv) convert_to_ex_master(ppzv, long, LONG)
#define convert_to_double_ex(ppzv) convert_to_ex_master(ppzv, double, DOUBLE)
#define convert_to_string_ex(ppzv) convert_to_ex_master(ppzv, string, STRING)
#define convert_to_array_ex(ppzv) convert_to_ex_master(ppzv, array, ARRAY)
#define convert_to_object_ex(ppzv) convert_to_ex_master(ppzv, object, OBJECT)
#define convert_to_null_ex(ppzv) convert_to_ex_master(ppzv, null, NULL)
#define convert_to_boolean_ex(pzv) convert_to_ex_master(pzv, boolean, BOOL)
#define convert_to_long_ex(pzv) convert_to_ex_master(pzv, long, LONG)
#define convert_to_double_ex(pzv) convert_to_ex_master(pzv, double, DOUBLE)
#define convert_to_string_ex(pzv) convert_to_ex_master(pzv, string, STRING)
#define convert_to_array_ex(pzv) convert_to_ex_master(pzv, array, ARRAY)
#define convert_to_object_ex(pzv) convert_to_ex_master(pzv, object, OBJECT)
#define convert_to_null_ex(pzv) convert_to_ex_master(pzv, null, NULL)
#define convert_scalar_to_number_ex(ppzv) \
if (Z_TYPE_PP(ppzv)!=IS_LONG && Z_TYPE_PP(ppzv)!=IS_DOUBLE) { \
if (!Z_ISREF_PP(ppzv)) { \
SEPARATE_ZVAL(ppzv); \
#define convert_scalar_to_number_ex(pzv) \
if (Z_TYPE_P(pzv)!=IS_LONG && Z_TYPE_P(pzv)!=IS_DOUBLE) { \
if (!Z_ISREF_P(pzv)) { \
SEPARATE_ZVAL(pzv); \
} \
convert_scalar_to_number(*ppzv TSRMLS_CC); \
convert_scalar_to_number(ppzv TSRMLS_CC); \
}
#define Z_LVAL(zval) (zval).value.lval
#define Z_BVAL(zval) ((zend_bool)(zval).value.lval)
#define Z_DVAL(zval) (zval).value.dval
#define Z_STRVAL(zval) (zval).value.str.val
#define Z_STRLEN(zval) (zval).value.str.len
#define Z_ARRVAL(zval) (zval).value.ht
#define Z_AST(zval) (zval).value.ast
#define Z_OBJVAL(zval) (zval).value.obj
#define Z_OBJ_HANDLE(zval) Z_OBJVAL(zval).handle
#define Z_OBJ_HT(zval) Z_OBJVAL(zval).handlers
#define Z_OBJCE(zval) zend_get_class_entry(&(zval) TSRMLS_CC)
#define Z_OBJPROP(zval) Z_OBJ_HT((zval))->get_properties(&(zval) TSRMLS_CC)
#define Z_OBJ_HANDLER(zval, hf) Z_OBJ_HT((zval))->hf
#define Z_RESVAL(zval) (zval).value.lval
#define Z_OBJDEBUG(zval,is_tmp) (Z_OBJ_HANDLER((zval),get_debug_info)?Z_OBJ_HANDLER((zval),get_debug_info)(&(zval),&is_tmp TSRMLS_CC):(is_tmp=0,Z_OBJ_HANDLER((zval),get_properties)?Z_OBJPROP(zval):NULL))
#define Z_LVAL_P(zval_p) Z_LVAL(*zval_p)
#define Z_BVAL_P(zval_p) Z_BVAL(*zval_p)
#define Z_DVAL_P(zval_p) Z_DVAL(*zval_p)
#define Z_STRVAL_P(zval_p) Z_STRVAL(*zval_p)
#define Z_STRLEN_P(zval_p) Z_STRLEN(*zval_p)
#define Z_ARRVAL_P(zval_p) Z_ARRVAL(*zval_p)
#define Z_AST_P(zval_p) Z_AST(*zval_p)
#define Z_OBJPROP_P(zval_p) Z_OBJPROP(*zval_p)
#define Z_OBJCE_P(zval_p) Z_OBJCE(*zval_p)
#define Z_RESVAL_P(zval_p) Z_RESVAL(*zval_p)
#define Z_OBJVAL_P(zval_p) Z_OBJVAL(*zval_p)
#define Z_OBJ_HANDLE_P(zval_p) Z_OBJ_HANDLE(*zval_p)
#define Z_OBJ_HT_P(zval_p) Z_OBJ_HT(*zval_p)
#define Z_OBJ_HANDLER_P(zval_p, h) Z_OBJ_HANDLER(*zval_p, h)
#define Z_OBJDEBUG_P(zval_p,is_tmp) Z_OBJDEBUG(*zval_p,is_tmp)
#define Z_LVAL_PP(zval_pp) Z_LVAL(**zval_pp)
#define Z_BVAL_PP(zval_pp) Z_BVAL(**zval_pp)
#define Z_DVAL_PP(zval_pp) Z_DVAL(**zval_pp)
#define Z_STRVAL_PP(zval_pp) Z_STRVAL(**zval_pp)
#define Z_STRLEN_PP(zval_pp) Z_STRLEN(**zval_pp)
#define Z_ARRVAL_PP(zval_pp) Z_ARRVAL(**zval_pp)
#define Z_AST_PP(zval_p) Z_AST(**zval_p)
#define Z_OBJPROP_PP(zval_pp) Z_OBJPROP(**zval_pp)
#define Z_OBJCE_PP(zval_pp) Z_OBJCE(**zval_pp)
#define Z_RESVAL_PP(zval_pp) Z_RESVAL(**zval_pp)
#define Z_OBJVAL_PP(zval_pp) Z_OBJVAL(**zval_pp)
#define Z_OBJ_HANDLE_PP(zval_p) Z_OBJ_HANDLE(**zval_p)
#define Z_OBJ_HT_PP(zval_p) Z_OBJ_HT(**zval_p)
#define Z_OBJ_HANDLER_PP(zval_p, h) Z_OBJ_HANDLER(**zval_p, h)
#define Z_OBJDEBUG_PP(zval_pp,is_tmp) Z_OBJDEBUG(**zval_pp,is_tmp)
#define Z_TYPE(zval) (zval).type
#define Z_TYPE_P(zval_p) Z_TYPE(*zval_p)
#define Z_TYPE_PP(zval_pp) Z_TYPE(**zval_pp)
#if HAVE_SETLOCALE && defined(ZEND_WIN32) && !defined(ZTS) && defined(_MSC_VER) && (_MSC_VER >= 1400)
/* This is performance improvement of tolower() on Windows and VC2005
* Gives 10-18% on bench.php

View file

@ -161,6 +161,27 @@ ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, int type, int (*
}
}
ZEND_API void zend_stack_clean(zend_stack *stack, void (*func)(void *), zend_bool free_elements)
{
int i;
if (func) {
for (i = 0; i < stack->top; i++) {
func(stack->elements[i]);
}
}
if (free_elements) {
if (stack->elements) {
for (i = 0; i < stack->top; i++) {
efree(stack->elements[i]);
}
efree(stack->elements);
stack->elements = NULL;
}
stack->top = stack->max = 0;
}
}
/*
* Local variables:
* tab-width: 4

View file

@ -42,6 +42,7 @@ ZEND_API void **zend_stack_base(const zend_stack *stack);
ZEND_API int zend_stack_count(const zend_stack *stack);
ZEND_API void zend_stack_apply(zend_stack *stack, int type, int (*apply_function)(void *element));
ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, int type, int (*apply_function)(void *element, void *arg), void *arg);
ZEND_API void zend_stack_clean(zend_stack *stack, void (*func)(void *), zend_bool free_elements);
END_EXTERN_C()
#define ZEND_STACK_APPLY_TOPDOWN 1

View file

@ -21,48 +21,40 @@
#include "zend.h"
#include "zend_globals.h"
#ifndef ZEND_DEBUG_INTERNED_STRINGS
# define ZEND_DEBUG_INTERNED_STRINGS 0
#endif
#if ZEND_DEBUG_INTERNED_STRINGS
# include <sys/mman.h>
#endif
ZEND_API const char *(*zend_new_interned_string)(const char *str, int len, int free_src TSRMLS_DC);
ZEND_API zend_string *(*zend_new_interned_string)(zend_string *str TSRMLS_DC);
ZEND_API void (*zend_interned_strings_snapshot)(TSRMLS_D);
ZEND_API void (*zend_interned_strings_restore)(TSRMLS_D);
static const char *zend_new_interned_string_int(const char *str, int len, int free_src TSRMLS_DC);
static zend_string *zend_new_interned_string_int(zend_string *str TSRMLS_DC);
static void zend_interned_strings_snapshot_int(TSRMLS_D);
static void zend_interned_strings_restore_int(TSRMLS_D);
ZEND_API zend_ulong zend_hash_func(const char *str, uint len)
{
return zend_inline_hash_func(str, len);
}
void zend_interned_strings_init(TSRMLS_D)
{
#ifndef ZTS
size_t size = 1024 * 1024;
#if ZEND_DEBUG_INTERNED_STRINGS
CG(interned_strings_start) = valloc(size);
#else
CG(interned_strings_start) = malloc(size);
#endif
CG(interned_strings_top) = CG(interned_strings_start);
CG(interned_strings_snapshot_top) = CG(interned_strings_start);
CG(interned_strings_end) = CG(interned_strings_start) + size;
zend_string *str;
zend_hash_init(&CG(interned_strings), 0, NULL, NULL, 1);
CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1;
CG(interned_strings).arBuckets = (Bucket **) pecalloc(CG(interned_strings).nTableSize, sizeof(Bucket *), CG(interned_strings).persistent);
CG(interned_strings).arData = (Bucket*) pecalloc(CG(interned_strings).nTableSize, sizeof(Bucket), CG(interned_strings).flags & HASH_FLAG_PERSISTENT);
CG(interned_strings).arHash = (zend_uint*) pecalloc(CG(interned_strings).nTableSize, sizeof(zend_uint), CG(interned_strings).flags & HASH_FLAG_PERSISTENT);
memset(CG(interned_strings).arHash, INVALID_IDX, CG(interned_strings).nTableSize * sizeof(zend_uint));
#if ZEND_DEBUG_INTERNED_STRINGS
mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
#endif
/* interned empty string */
CG(interned_empty_string) = zend_new_interned_string_int("", sizeof(""), 0 TSRMLS_CC);
/* interned empty string */
str = STR_ALLOC(sizeof("")-1, 1);
str->val[0] = '\000';
CG(empty_string) = zend_new_interned_string_int(str TSRMLS_CC);
#else
str = STR_ALLOC(sizeof("")-1, 1);
str->val[0] = '\000';
str->gc.u.v.flags |= IS_STR_INTERNED;
CG(empty_string) = str;
#endif
zend_new_interned_string = zend_new_interned_string_int;
@ -73,94 +65,68 @@ void zend_interned_strings_init(TSRMLS_D)
void zend_interned_strings_dtor(TSRMLS_D)
{
#ifndef ZTS
#if ZEND_DEBUG_INTERNED_STRINGS
mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_WRITE | PROT_READ);
#endif
free(CG(interned_strings).arBuckets);
free(CG(interned_strings_start));
free(CG(interned_strings).arData);
free(CG(interned_strings).arHash);
#endif
}
static const char *zend_new_interned_string_int(const char *arKey, int nKeyLength, int free_src TSRMLS_DC)
static zend_string *zend_new_interned_string_int(zend_string *str TSRMLS_DC)
{
#ifndef ZTS
ulong h;
uint nIndex;
uint idx;
Bucket *p;
if (IS_INTERNED(arKey)) {
return arKey;
if (IS_INTERNED(str)) {
return str;
}
h = zend_inline_hash_func(arKey, nKeyLength);
h = STR_HASH_VAL(str);
nIndex = h & CG(interned_strings).nTableMask;
p = CG(interned_strings).arBuckets[nIndex];
while (p != NULL) {
if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
if (!memcmp(p->arKey, arKey, nKeyLength)) {
if (free_src) {
efree((void *)arKey);
}
return p->arKey;
idx = CG(interned_strings).arHash[nIndex];
while (idx != INVALID_IDX) {
p = CG(interned_strings).arData + idx;
if ((p->h == h) && (p->key->len == str->len)) {
if (!memcmp(p->key->val, str->val, str->len)) {
//??? if (free_src) {
//??? efree((void *)arKey);
//??? }
return p->key;
}
}
p = p->pNext;
idx = p->val.u.next;
}
if (CG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength) >=
CG(interned_strings_end)) {
/* no memory */
return arKey;
}
str->gc.refcount = 1;
// str->gc.u.v.type = IS_INTERNED_STRING;
str->gc.u.v.flags |= IS_STR_INTERNED;
p = (Bucket *) CG(interned_strings_top);
CG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength);
//??? if (CG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength) >=
//??? CG(interned_strings_end)) {
//??? /* no memory */
//??? return arKey;
//??? }
#if ZEND_DEBUG_INTERNED_STRINGS
mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ | PROT_WRITE);
#endif
//??? info = (zend_string_info*) CG(interned_strings_top);
//??? CG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(zend_string_info) + nKeyLength);
//??? memcpy((char*)(info+1), arKey, nKeyLength);
//??? if (free_src) {
//??? efree((void *)arKey);
//??? }
//??? info->nKeyLength = nKeyLength;
//??? info->h = h;
p->arKey = (char*)(p+1);
memcpy((char*)p->arKey, arKey, nKeyLength);
if (free_src) {
efree((void *)arKey);
}
p->nKeyLength = nKeyLength;
p->h = h;
p->pData = &p->pDataPtr;
p->pDataPtr = p;
p->pNext = CG(interned_strings).arBuckets[nIndex];
p->pLast = NULL;
if (p->pNext) {
p->pNext->pLast = p;
}
HANDLE_BLOCK_INTERRUPTIONS();
p->pListLast = CG(interned_strings).pListTail;
CG(interned_strings).pListTail = p;
p->pListNext = NULL;
if (p->pListLast != NULL) {
p->pListLast->pListNext = p;
}
if (!CG(interned_strings).pListHead) {
CG(interned_strings).pListHead = p;
}
CG(interned_strings).arBuckets[nIndex] = p;
HANDLE_UNBLOCK_INTERRUPTIONS();
CG(interned_strings).nNumOfElements++;
if (CG(interned_strings).nNumOfElements > CG(interned_strings).nTableSize) {
if (CG(interned_strings).nNumUsed >= CG(interned_strings).nTableSize) {
if ((CG(interned_strings).nTableSize << 1) > 0) { /* Let's double the table size */
Bucket **t = (Bucket **) perealloc_recoverable(CG(interned_strings).arBuckets, (CG(interned_strings).nTableSize << 1) * sizeof(Bucket *), CG(interned_strings).persistent);
Bucket *d = (Bucket *) perealloc_recoverable(CG(interned_strings).arData, (CG(interned_strings).nTableSize << 1) * sizeof(Bucket), CG(interned_strings).flags & HASH_FLAG_PERSISTENT);
zend_uint *h = (zend_uint *) perealloc_recoverable(CG(interned_strings).arHash, (CG(interned_strings).nTableSize << 1) * sizeof(zend_uint), CG(interned_strings).flags & HASH_FLAG_PERSISTENT);
if (t) {
if (d && h) {
HANDLE_BLOCK_INTERRUPTIONS();
CG(interned_strings).arBuckets = t;
CG(interned_strings).arData = d;
CG(interned_strings).arHash = h;
CG(interned_strings).nTableSize = (CG(interned_strings).nTableSize << 1);
CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1;
zend_hash_rehash(&CG(interned_strings));
@ -169,60 +135,68 @@ static const char *zend_new_interned_string_int(const char *arKey, int nKeyLengt
}
}
#if ZEND_DEBUG_INTERNED_STRINGS
mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
#endif
HANDLE_BLOCK_INTERRUPTIONS();
idx = CG(interned_strings).nNumUsed++;
CG(interned_strings).nNumOfElements++;
p = CG(interned_strings).arData + idx;
p->h = h;
p->key = str;
Z_STR(p->val) = str;
Z_TYPE(p->val) = IS_STRING;
nIndex = h & CG(interned_strings).nTableMask;
p->val.u.next = CG(interned_strings).arHash[nIndex];
CG(interned_strings).arHash[nIndex] = idx;
HANDLE_UNBLOCK_INTERRUPTIONS();
return p->arKey;
return str;
#else
return arKey;
return str;
#endif
}
static void zend_interned_strings_snapshot_int(TSRMLS_D)
{
CG(interned_strings_snapshot_top) = CG(interned_strings_top);
#ifndef ZTS
uint idx;
Bucket *p;
idx = CG(interned_strings).nNumUsed;
while (idx > 0) {
idx--;
p = CG(interned_strings).arData + idx;
p->key->gc.u.v.flags |= IS_STR_PERMANENT;
}
#endif
}
static void zend_interned_strings_restore_int(TSRMLS_D)
{
#ifndef ZTS
uint nIndex;
uint idx;
Bucket *p;
int i;
#endif
CG(interned_strings_top) = CG(interned_strings_snapshot_top);
idx = CG(interned_strings).nNumUsed;
while (idx > 0) {
idx--;
p = CG(interned_strings).arData + idx;
if (!(p->key->gc.u.v.flags & IS_STR_PERMANENT)) break;
CG(interned_strings).nNumUsed--;
CG(interned_strings).nNumOfElements--;
#ifndef ZTS
#if ZEND_DEBUG_INTERNED_STRINGS
mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_WRITE | PROT_READ);
#endif
for (i = 0; i < CG(interned_strings).nTableSize; i++) {
p = CG(interned_strings).arBuckets[i];
while (p && p->arKey > CG(interned_strings_top)) {
CG(interned_strings).nNumOfElements--;
if (p->pListLast != NULL) {
p->pListLast->pListNext = p->pListNext;
} else {
CG(interned_strings).pListHead = p->pListNext;
}
if (p->pListNext != NULL) {
p->pListNext->pListLast = p->pListLast;
} else {
CG(interned_strings).pListTail = p->pListLast;
}
p = p->pNext;
}
if (p) {
p->pLast = NULL;
}
CG(interned_strings).arBuckets[i] = p;
}
#if ZEND_DEBUG_INTERNED_STRINGS
mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
#endif
nIndex = p->h & CG(interned_strings).nTableMask;
if (CG(interned_strings).arHash[nIndex] == idx) {
CG(interned_strings).arHash[nIndex] = p->val.u.next;
} else {
uint prev = CG(interned_strings).arHash[nIndex];
while (CG(interned_strings).arData[prev].val.u.next != idx) {
prev = CG(interned_strings).arData[prev].val.u.next;
}
CG(interned_strings).arData[prev].val.u.next = p->val.u.next;
}
}
#endif
}

View file

@ -24,70 +24,211 @@
#include "zend.h"
BEGIN_EXTERN_C()
ZEND_API extern const char *(*zend_new_interned_string)(const char *str, int len, int free_src TSRMLS_DC);
ZEND_API extern zend_string *(*zend_new_interned_string)(zend_string *str TSRMLS_DC);
ZEND_API extern void (*zend_interned_strings_snapshot)(TSRMLS_D);
ZEND_API extern void (*zend_interned_strings_restore)(TSRMLS_D);
ZEND_API zend_ulong zend_hash_func(const char *str, uint len);
void zend_interned_strings_init(TSRMLS_D);
void zend_interned_strings_dtor(TSRMLS_D);
END_EXTERN_C()
#ifndef ZTS
#define IS_INTERNED(s) \
(((s) >= CG(interned_strings_start)) && ((s) < CG(interned_strings_end)))
# define IS_INTERNED(s) ((s)->gc.u.v.flags & IS_STR_INTERNED)
#else
#define IS_INTERNED(s) \
(0)
# define IS_INTERNED(s) 0
#endif
#define INTERNED_LEN(s) \
(((Bucket*)(((char*)(s))-sizeof(Bucket)))->nKeyLength)
#define STR_HASH_VAL(s) zend_str_hash_val(s)
#define STR_FORGET_HASH_VAL(s) zend_str_forget_hash_val(s)
#define INTERNED_HASH(s) \
(((Bucket*)(((char*)(s))-sizeof(Bucket)))->h)
#define STR_REFCOUNT(s) zend_str_refcount(s)
#define STR_ADDREF(s) zend_str_addref(s)
#define STR_DELREF(s) zend_str_delref(s)
#define STR_ALLOC(len, persistent) zend_str_alloc(len, persistent)
#define STR_INIT(str, len, persistent) zend_str_init(str, len, persistent)
#define STR_COPY(s) zend_str_copy(s)
#define STR_DUP(s, persistent) zend_str_dup(s, persistent)
#define STR_EREALLOC(s, len) zend_str_erealloc(s, len)
#define STR_FREE(s) zend_str_free(s)
#define STR_RELEASE(s) zend_str_release(s)
#define STR_EMPTY_ALLOC() CG(empty_string)
#define str_efree(s) do { \
if (!IS_INTERNED(s)) { \
efree((char*)s); \
} \
} while (0)
#define str_efree_rel(s) do { \
if (!IS_INTERNED(s)) { \
efree_rel((char *)s); \
} \
} while (0)
#define str_free(s) do { \
if (!IS_INTERNED(s)) { \
free((char*)s); \
} \
} while (0)
#define str_erealloc(str, new_len) \
(IS_INTERNED(str) \
? _str_erealloc(str, new_len, INTERNED_LEN(str)) \
: erealloc(str, new_len))
static inline char *_str_erealloc(char *str, size_t new_len, size_t old_len) {
char *buf = (char *) emalloc(new_len);
memcpy(buf, str, old_len);
return buf;
static zend_always_inline zend_ulong zend_str_hash_val(zend_string *s)
{
if (!s->h) {
s->h = zend_hash_func(s->val, s->len + 1);
}
return s->h;
}
#define str_estrndup(str, len) \
(IS_INTERNED(str) ? (str) : estrndup((str), (len)))
static zend_always_inline void zend_str_forget_hash_val(zend_string *s)
{
s->h = 0;
}
#define str_strndup(str, len) \
(IS_INTERNED(str) ? (str) : zend_strndup((str), (len)));
static zend_always_inline zend_uint zend_str_refcount(zend_string *s)
{
if (!IS_INTERNED(s)) {
return s->gc.refcount;
}
return 1;
}
#define str_hash(str, len) \
(IS_INTERNED(str) ? INTERNED_HASH(str) : zend_hash_func((str), (len)+1))
static zend_always_inline zend_uint zend_str_addref(zend_string *s)
{
if (!IS_INTERNED(s)) {
return ++s->gc.refcount;
}
return 1;
}
static zend_always_inline zend_uint zend_str_delref(zend_string *s)
{
if (!IS_INTERNED(s)) {
return --s->gc.refcount;
}
return 1;
}
static zend_always_inline zend_string *zend_str_alloc(int len, int persistent)
{
zend_string *ret = pemalloc(sizeof(zend_string) + len, persistent);
ret->gc.refcount = 1;
ret->gc.u.v.type = IS_STRING;
ret->gc.u.v.flags = (persistent ? IS_STR_PERSISTENT : 0);
ret->h = 0;
ret->len = len;
return ret;
}
static zend_always_inline zend_string *zend_str_init(const char *str, int len, int persistent)
{
zend_string *ret = STR_ALLOC(len, persistent);
memcpy(ret, str, len + 1);
return ret;
}
static zend_always_inline zend_string *zend_str_copy(zend_string *s)
{
if (!IS_INTERNED(s)) {
STR_ADDREF(s);
}
return s;
}
static zend_always_inline zend_string *zend_str_dup(zend_string *s, int persistent)
{
if (IS_INTERNED(s)) {
return s;
} else {
return STR_INIT(s->val, s->len, persistent);
}
}
static zend_always_inline zend_string *zend_str_erealloc(zend_string *s, int len)
{
zend_string *ret;
if (IS_INTERNED(s)) {
ret = STR_ALLOC(len, 0);
memcpy(ret->val, s->val, (len > s->len ? s->len : len) + 1);
} else if (STR_REFCOUNT(s) == 1) {
ret = erealloc(s, sizeof(zend_string) + len);
ret->len = len;
STR_FORGET_HASH_VAL(ret);
} else {
ret = STR_ALLOC(len, 0);
memcpy(ret->val, s->val, (len > s->len ? s->len : len) + 1);
STR_DELREF(s);
}
return ret;
}
static zend_always_inline void zend_str_free(zend_string *s)
{
if (!IS_INTERNED(s)) {
pefree(s, s->gc.u.v.flags & IS_STR_PERSISTENT);
}
}
static zend_always_inline void zend_str_release(zend_string *s)
{
if (!IS_INTERNED(s)) {
if (STR_DELREF(s) == 0) {
STR_FREE(s);
}
}
}
/*
* DJBX33A (Daniel J. Bernstein, Times 33 with Addition)
*
* This is Daniel J. Bernstein's popular `times 33' hash function as
* posted by him years ago on comp.lang.c. It basically uses a function
* like ``hash(i) = hash(i-1) * 33 + str[i]''. This is one of the best
* known hash functions for strings. Because it is both computed very
* fast and distributes very well.
*
* The magic of number 33, i.e. why it works better than many other
* constants, prime or not, has never been adequately explained by
* anyone. So I try an explanation: if one experimentally tests all
* multipliers between 1 and 256 (as RSE did now) one detects that even
* numbers are not useable at all. The remaining 128 odd numbers
* (except for the number 1) work more or less all equally well. They
* all distribute in an acceptable way and this way fill a hash table
* with an average percent of approx. 86%.
*
* If one compares the Chi^2 values of the variants, the number 33 not
* even has the best value. But the number 33 and a few other equally
* good numbers like 17, 31, 63, 127 and 129 have nevertheless a great
* advantage to the remaining numbers in the large set of possible
* multipliers: their multiply operation can be replaced by a faster
* operation based on just one shift plus either a single addition
* or subtraction operation. And because a hash function has to both
* distribute good _and_ has to be very fast to compute, those few
* numbers should be preferred and seems to be the reason why Daniel J.
* Bernstein also preferred it.
*
*
* -- Ralf S. Engelschall <rse@engelschall.com>
*/
static inline ulong zend_inline_hash_func(const char *str, uint len)
{
register ulong hash = 5381;
/* variant with the hash unrolled eight times */
for (; len >= 8; len -= 8) {
hash = ((hash << 5) + hash) + *str++;
hash = ((hash << 5) + hash) + *str++;
hash = ((hash << 5) + hash) + *str++;
hash = ((hash << 5) + hash) + *str++;
hash = ((hash << 5) + hash) + *str++;
hash = ((hash << 5) + hash) + *str++;
hash = ((hash << 5) + hash) + *str++;
hash = ((hash << 5) + hash) + *str++;
}
switch (len) {
case 7: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
case 6: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
case 5: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
case 4: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
case 3: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
case 2: hash = ((hash << 5) + hash) + *str++; /* fallthrough... */
case 1: hash = ((hash << 5) + hash) + *str++; break;
case 0: break;
EMPTY_SWITCH_DEFAULT_CASE()
}
return hash;
}
//???#define str_estrndup(str, len) (IS_INTERNED(str) ? (str) : estrndup((str), (len)))
//???#define str_strndup(str, len) (IS_INTERNED(str) ? (str) : zend_strndup((str), (len)));
#endif /* ZEND_STRING_H */

View file

@ -99,45 +99,34 @@ ZEND_API void zend_ts_hash_clean(TsHashTable *ht)
end_write(ht);
}
ZEND_API int _zend_ts_hash_add_or_update(TsHashTable *ht, char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC)
ZEND_API zval *_zend_ts_hash_add_or_update(TsHashTable *ht, zend_string *key, zval *pData, int flag ZEND_FILE_LINE_DC)
{
int retval;
zval *retval;
begin_write(ht);
retval = _zend_hash_add_or_update(TS_HASH(ht), arKey, nKeyLength, pData, nDataSize, pDest, flag ZEND_FILE_LINE_RELAY_CC);
retval = _zend_hash_add_or_update(TS_HASH(ht), key, pData, flag ZEND_FILE_LINE_RELAY_CC);
end_write(ht);
return retval;
}
ZEND_API int _zend_ts_hash_quick_add_or_update(TsHashTable *ht, char *arKey, uint nKeyLength, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC)
ZEND_API zval *_zend_ts_hash_index_update_or_next_insert(TsHashTable *ht, ulong h, zval *pData, int flag ZEND_FILE_LINE_DC)
{
int retval;
zval *retval;
begin_write(ht);
retval = _zend_hash_quick_add_or_update(TS_HASH(ht), arKey, nKeyLength, h, pData, nDataSize, pDest, flag ZEND_FILE_LINE_RELAY_CC);
retval = _zend_hash_index_update_or_next_insert(TS_HASH(ht), h, pData, flag ZEND_FILE_LINE_RELAY_CC);
end_write(ht);
return retval;
}
ZEND_API int _zend_ts_hash_index_update_or_next_insert(TsHashTable *ht, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC)
ZEND_API zval *zend_ts_hash_add_empty_element(TsHashTable *ht, zend_string *key)
{
int retval;
zval *retval;
begin_write(ht);
retval = _zend_hash_index_update_or_next_insert(TS_HASH(ht), h, pData, nDataSize, pDest, flag ZEND_FILE_LINE_RELAY_CC);
end_write(ht);
return retval;
}
ZEND_API int zend_ts_hash_add_empty_element(TsHashTable *ht, char *arKey, uint nKeyLength)
{
int retval;
begin_write(ht);
retval = zend_hash_add_empty_element(TS_HASH(ht), arKey, nKeyLength);
retval = zend_hash_add_empty_element(TS_HASH(ht), key);
end_write(ht);
return retval;
@ -187,67 +176,56 @@ ZEND_API void zend_ts_hash_reverse_apply(TsHashTable *ht, apply_func_t apply_fun
end_write(ht);
}
ZEND_API int zend_ts_hash_del_key_or_index(TsHashTable *ht, char *arKey, uint nKeyLength, ulong h, int flag)
ZEND_API int zend_ts_hash_del(TsHashTable *ht, zend_string *key)
{
int retval;
begin_write(ht);
retval = zend_hash_del_key_or_index(TS_HASH(ht), arKey, nKeyLength, h, flag);
retval = zend_hash_del(TS_HASH(ht), key);
end_write(ht);
return retval;
}
ZEND_API ulong zend_ts_get_hash_value(TsHashTable *ht, char *arKey, uint nKeyLength)
ZEND_API int zend_ts_hash_index_del(TsHashTable *ht, ulong h)
{
ulong retval;
int retval;
begin_write(ht);
retval = zend_hash_index_del(TS_HASH(ht), h);
end_write(ht);
return retval;
}
ZEND_API zval *zend_ts_hash_find(TsHashTable *ht, zend_string *key)
{
zval *retval;
begin_read(ht);
retval = zend_get_hash_value(arKey, nKeyLength);
retval = zend_hash_find(TS_HASH(ht), key);
end_read(ht);
return retval;
}
ZEND_API int zend_ts_hash_find(TsHashTable *ht, char *arKey, uint nKeyLength, void **pData)
ZEND_API zval *zend_ts_hash_index_find(TsHashTable *ht, ulong h)
{
int retval;
zval *retval;
begin_read(ht);
retval = zend_hash_find(TS_HASH(ht), arKey, nKeyLength, pData);
retval = zend_hash_index_find(TS_HASH(ht), h);
end_read(ht);
return retval;
}
ZEND_API int zend_ts_hash_quick_find(TsHashTable *ht, char *arKey, uint nKeyLength, ulong h, void **pData)
ZEND_API int zend_ts_hash_exists(TsHashTable *ht, zend_string *key)
{
int retval;
begin_read(ht);
retval = zend_hash_quick_find(TS_HASH(ht), arKey, nKeyLength, h, pData);
end_read(ht);
return retval;
}
ZEND_API int zend_ts_hash_index_find(TsHashTable *ht, ulong h, void **pData)
{
int retval;
begin_read(ht);
retval = zend_hash_index_find(TS_HASH(ht), h, pData);
end_read(ht);
return retval;
}
ZEND_API int zend_ts_hash_exists(TsHashTable *ht, char *arKey, uint nKeyLength)
{
int retval;
begin_read(ht);
retval = zend_hash_exists(TS_HASH(ht), arKey, nKeyLength);
retval = zend_hash_exists(TS_HASH(ht), key);
end_read(ht);
return retval;
@ -264,36 +242,36 @@ ZEND_API int zend_ts_hash_index_exists(TsHashTable *ht, ulong h)
return retval;
}
ZEND_API void zend_ts_hash_copy(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size)
ZEND_API void zend_ts_hash_copy(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor)
{
begin_read(source);
begin_write(target);
zend_hash_copy(TS_HASH(target), TS_HASH(source), pCopyConstructor, tmp, size);
zend_hash_copy(TS_HASH(target), TS_HASH(source), pCopyConstructor);
end_write(target);
end_read(source);
}
ZEND_API void zend_ts_hash_copy_to_hash(HashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size)
ZEND_API void zend_ts_hash_copy_to_hash(HashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor)
{
begin_read(source);
zend_hash_copy(target, TS_HASH(source), pCopyConstructor, tmp, size);
zend_hash_copy(target, TS_HASH(source), pCopyConstructor);
end_read(source);
}
ZEND_API void zend_ts_hash_merge(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, int overwrite)
ZEND_API void zend_ts_hash_merge(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, int overwrite)
{
begin_read(source);
begin_write(target);
zend_hash_merge(TS_HASH(target), TS_HASH(source), pCopyConstructor, tmp, size, overwrite);
zend_hash_merge(TS_HASH(target), TS_HASH(source), pCopyConstructor, overwrite);
end_write(target);
end_read(source);
}
ZEND_API void zend_ts_hash_merge_ex(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, uint size, merge_checker_func_t pMergeSource, void *pParam)
ZEND_API void zend_ts_hash_merge_ex(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, merge_checker_func_t pMergeSource, void *pParam)
{
begin_read(source);
begin_write(target);
zend_hash_merge_ex(TS_HASH(target), TS_HASH(source), pCopyConstructor, size, pMergeSource, pParam);
zend_hash_merge_ex(TS_HASH(target), TS_HASH(source), pCopyConstructor, pMergeSource, pParam);
end_write(target);
end_read(source);
}
@ -322,12 +300,12 @@ ZEND_API int zend_ts_hash_compare(TsHashTable *ht1, TsHashTable *ht2, compare_fu
return retval;
}
ZEND_API int zend_ts_hash_minmax(TsHashTable *ht, compare_func_t compar, int flag, void **pData TSRMLS_DC)
ZEND_API zval *zend_ts_hash_minmax(TsHashTable *ht, compare_func_t compar, int flag TSRMLS_DC)
{
int retval;
zval *retval;
begin_read(ht);
retval = zend_hash_minmax(TS_HASH(ht), compar, flag, pData TSRMLS_CC);
retval = zend_hash_minmax(TS_HASH(ht), compar, flag TSRMLS_CC);
end_read(ht);
return retval;
@ -355,22 +333,6 @@ ZEND_API int zend_ts_hash_rehash(TsHashTable *ht)
return retval;
}
#if ZEND_DEBUG
void zend_ts_hash_display_pListTail(TsHashTable *ht)
{
begin_read(ht);
zend_hash_display_pListTail(TS_HASH(ht));
end_read(ht);
}
void zend_ts_hash_display(TsHashTable *ht)
{
begin_read(ht);
zend_hash_display(TS_HASH(ht));
end_read(ht);
}
#endif
/*
* Local variables:
* tab-width: 4

View file

@ -49,25 +49,19 @@ ZEND_API void zend_ts_hash_clean(TsHashTable *ht);
/* additions/updates/changes */
ZEND_API int _zend_ts_hash_add_or_update(TsHashTable *ht, char *arKey, uint nKeyLength, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
#define zend_ts_hash_update(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
_zend_ts_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_ts_hash_add(ht, arKey, nKeyLength, pData, nDataSize, pDest) \
_zend_ts_hash_add_or_update(ht, arKey, nKeyLength, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
ZEND_API zval *_zend_ts_hash_add_or_update(TsHashTable *ht, zend_string *key, zval *pData, int flag ZEND_FILE_LINE_DC);
#define zend_ts_hash_update(ht, key, pData) \
_zend_ts_hash_add_or_update(ht, key, pData, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_ts_hash_add(ht, key, pData) \
_zend_ts_hash_add_or_update(ht, key, pData, HASH_ADD ZEND_FILE_LINE_CC)
ZEND_API int _zend_ts_hash_quick_add_or_update(TsHashTable *ht, char *arKey, uint nKeyLength, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
#define zend_ts_hash_quick_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest) \
_zend_ts_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_ts_hash_quick_add(ht, arKey, nKeyLength, h, pData, nDataSize, pDest) \
_zend_ts_hash_quick_add_or_update(ht, arKey, nKeyLength, h, pData, nDataSize, pDest, HASH_ADD ZEND_FILE_LINE_CC)
ZEND_API zval *_zend_ts_hash_index_update_or_next_insert(TsHashTable *ht, ulong h, zval *pData, int flag ZEND_FILE_LINE_DC);
#define zend_ts_hash_index_update(ht, h, pData) \
_zend_ts_hash_index_update_or_next_insert(ht, h, pData, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_ts_hash_next_index_insert(ht, pData) \
_zend_ts_hash_index_update_or_next_insert(ht, 0, pData, HASH_NEXT_INSERT ZEND_FILE_LINE_CC)
ZEND_API int _zend_ts_hash_index_update_or_next_insert(TsHashTable *ht, ulong h, void *pData, uint nDataSize, void **pDest, int flag ZEND_FILE_LINE_DC);
#define zend_ts_hash_index_update(ht, h, pData, nDataSize, pDest) \
_zend_ts_hash_index_update_or_next_insert(ht, h, pData, nDataSize, pDest, HASH_UPDATE ZEND_FILE_LINE_CC)
#define zend_ts_hash_next_index_insert(ht, pData, nDataSize, pDest) \
_zend_ts_hash_index_update_or_next_insert(ht, 0, pData, nDataSize, pDest, HASH_NEXT_INSERT ZEND_FILE_LINE_CC)
ZEND_API int zend_ts_hash_add_empty_element(TsHashTable *ht, char *arKey, uint nKeyLength);
ZEND_API zval* zend_ts_hash_add_empty_element(TsHashTable *ht, zend_string *key);
ZEND_API void zend_ts_hash_graceful_destroy(TsHashTable *ht);
ZEND_API void zend_ts_hash_apply(TsHashTable *ht, apply_func_t apply_func TSRMLS_DC);
@ -78,38 +72,30 @@ ZEND_API void zend_ts_hash_reverse_apply(TsHashTable *ht, apply_func_t apply_fun
/* Deletes */
ZEND_API int zend_ts_hash_del_key_or_index(TsHashTable *ht, char *arKey, uint nKeyLength, ulong h, int flag);
#define zend_ts_hash_del(ht, arKey, nKeyLength) \
zend_ts_hash_del_key_or_index(ht, arKey, nKeyLength, 0, HASH_DEL_KEY)
#define zend_ts_hash_index_del(ht, h) \
zend_ts_hash_del_key_or_index(ht, NULL, 0, h, HASH_DEL_INDEX)
ZEND_API ulong zend_ts_get_hash_value(TsHashTable *ht, char *arKey, uint nKeyLength);
ZEND_API int zend_ts_hash_del(TsHashTable *ht, zend_string *key);
ZEND_API int zend_ts_hash_index_del(TsHashTable *ht, ulong h);
/* Data retreival */
ZEND_API int zend_ts_hash_find(TsHashTable *ht, char *arKey, uint nKeyLength, void **pData);
ZEND_API int zend_ts_hash_quick_find(TsHashTable *ht, char *arKey, uint nKeyLength, ulong h, void **pData);
ZEND_API int zend_ts_hash_index_find(TsHashTable *ht, ulong h, void **pData);
ZEND_API zval *zend_ts_hash_find(TsHashTable *ht, zend_string *key);
ZEND_API zval *zend_ts_hash_index_find(TsHashTable *ht, ulong);
/* Misc */
ZEND_API int zend_ts_hash_exists(TsHashTable *ht, char *arKey, uint nKeyLength);
ZEND_API int zend_ts_hash_exists(TsHashTable *ht, zend_string *key);
ZEND_API int zend_ts_hash_index_exists(TsHashTable *ht, ulong h);
/* Copying, merging and sorting */
ZEND_API void zend_ts_hash_copy(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size);
ZEND_API void zend_ts_hash_copy_to_hash(HashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size);
ZEND_API void zend_ts_hash_merge(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, int overwrite);
ZEND_API void zend_ts_hash_merge_ex(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, uint size, merge_checker_func_t pMergeSource, void *pParam);
ZEND_API void zend_ts_hash_copy(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor);
ZEND_API void zend_ts_hash_copy_to_hash(HashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor);
ZEND_API void zend_ts_hash_merge(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, int overwrite);
ZEND_API void zend_ts_hash_merge_ex(TsHashTable *target, TsHashTable *source, copy_ctor_func_t pCopyConstructor, merge_checker_func_t pMergeSource, void *pParam);
ZEND_API int zend_ts_hash_sort(TsHashTable *ht, sort_func_t sort_func, compare_func_t compare_func, int renumber TSRMLS_DC);
ZEND_API int zend_ts_hash_compare(TsHashTable *ht1, TsHashTable *ht2, compare_func_t compar, zend_bool ordered TSRMLS_DC);
ZEND_API int zend_ts_hash_minmax(TsHashTable *ht, compare_func_t compar, int flag, void **pData TSRMLS_DC);
ZEND_API zval *zend_ts_hash_minmax(TsHashTable *ht, compare_func_t compar, int flag TSRMLS_DC);
ZEND_API int zend_ts_hash_num_elements(TsHashTable *ht);
ZEND_API int zend_ts_hash_rehash(TsHashTable *ht);
ZEND_API ulong zend_ts_hash_func(char *arKey, uint nKeyLength);
#if ZEND_DEBUG
/* debug */
void zend_ts_hash_display_pListTail(TsHashTable *ht);

View file

@ -50,14 +50,423 @@ typedef long zend_intptr_t;
typedef unsigned long zend_uintptr_t;
#endif
typedef unsigned int zend_object_handle;
typedef struct _zend_object_handlers zend_object_handlers;
typedef struct _zval_struct zval;
typedef struct _zend_class_entry zend_class_entry;
typedef union _zend_function zend_function;
typedef struct _zend_object_value {
zend_object_handle handle;
typedef struct _zval_struct zval;
typedef struct _zend_refcounted zend_refcounted;
typedef struct _zend_string zend_string;
typedef struct _zend_array zend_array;
typedef struct _zend_object zend_object;
typedef struct _zend_resource zend_resource;
typedef struct _zend_reference zend_reference;
typedef struct _zend_ast_ref zend_ast_ref;
typedef struct _zend_ast zend_ast;
typedef struct _zend_str_offset zend_str_offset;
typedef void (*dtor_func_t)(zval *zv);
typedef union _zend_value {
long lval; /* long value */
double dval; /* double value */
zend_refcounted *counted;
zend_string *str;
zend_array *arr;
zend_object *obj;
zend_resource *res;
zend_reference *ref;
zend_ast_ref *ast;
zval *zv;
void *ptr;
zend_class_entry *ce;
zend_function *func;
zend_str_offset *str_offset;
} zend_value;
struct _zval_struct {
zend_value value; /* value */
zend_uchar type; /* active type */
union {
zend_uint next; /* hash collision chain */
} u;
};
struct _zend_refcounted {
zend_uint refcount; /* reference counter 32-bit */
union {
struct {
zend_uchar type;
zend_uchar flags; /* used for strings & objects */
zend_ushort buffer; /* keeps GC root number or 0 */
} v;
zend_uint long_type;
} u;
};
struct _zend_string {
zend_refcounted gc;
zend_ulong h; /* hash value */
int len;
char val[1];
};
struct _zend_str_offset {
zend_refcounted gc;
zend_string *str;
int offset;
};
typedef struct _Bucket {
zend_ulong h; /* hash value (or numeric index) */
zend_string *key; /* string key or NULL for numerics */
zval val;
} Bucket;
typedef struct _HashTable {
zend_uint nTableSize;
zend_uint nTableMask;
zend_uint nNumUsed;
zend_uint nNumOfElements;
long nNextFreeElement;
Bucket *arData;
zend_uint *arHash;
dtor_func_t pDestructor;
zend_uint nInternalPointer;
zend_uchar flags;
zend_uchar nApplyCount;
} HashTable;
struct _zend_array {
zend_refcounted gc;
HashTable ht;
};
struct _zend_object {
zend_refcounted gc;
zend_uint handle;
zend_class_entry *ce;
const zend_object_handlers *handlers;
} zend_object_value;
HashTable *properties;
HashTable *guards; /* protects from __get/__set ... recursion */
zval properties_table[1];
};
struct _zend_resource {
zend_refcounted gc;
long handle; //???
int type;
void *ptr;
};
struct _zend_reference {
zend_refcounted gc;
zval val;
};
struct _zend_ast_ref {
zend_refcounted gc;
zend_ast *ast;
};
/* data types */
#define IS_UNDEF 0
#define IS_NULL 1
#define IS_INDIRECT 2
#define IS_BOOL 3
#define IS_LONG 4
#define IS_DOUBLE 5
//#define IS_INTERNED_STRING 6
#define IS_STRING 7
#define IS_ARRAY 8
#define IS_OBJECT 9
#define IS_RESOURCE 10
#define IS_REFERENCE 11
#define IS_CONSTANT 12
#define IS_CONSTANT_ARRAY 13
#define IS_CONSTANT_AST 14
#define IS_CALLABLE 15
#define IS_STR_OFFSET 16
#define IS_PTR 17
/* Ugly hack to support constants as static array indices */
#define IS_CONSTANT_TYPE_MASK 0x00f
#define IS_CONSTANT_UNQUALIFIED 0x010
#define IS_CONSTANT_INDEX 0x080
#define IS_LEXICAL_VAR 0x020
#define IS_LEXICAL_REF 0x040
#define IS_CONSTANT_IN_NAMESPACE 0x100
#define IS_CONSTANT_TYPE(type) \
(((type) & IS_CONSTANT_TYPE_MASK) >= IS_CONSTANT && ((type) & IS_CONSTANT_TYPE_MASK) <= IS_CONSTANT_AST)
/* All data types < IS_STRING have their constructor/destructors skipped */
#define IS_REFCOUNTED(type) ((type) >= IS_STRING)
#define Z_TYPE(zval) (zval).type
#define Z_TYPE_P(zval_p) Z_TYPE(*(zval_p))
/* string flags (zval.value->gc.u.vflags) */
#define IS_STR_PERSISTENT (1<<0) /* allocated using malloc */
#define IS_STR_INTERNED (1<<1) /* interned string */
#define IS_STR_PERMANENT (1<<2) /* relives request boundary */
/* string flags (zval.value->gc.u.vflags) */
#define IS_OBJ_DESTRUCTOR_CALLED (1<<0)
#define Z_REFCOUNTED(zval) IS_REFCOUNTED(Z_TYPE(zval))
#define Z_REFCOUNTED_P(zval_p) Z_REFCOUNTED(*(zval_p))
#define Z_ISREF(zval) (Z_TYPE(zval) == IS_REFERENCE)
#define Z_ISREF_P(zval_p) Z_ISREF(*(zval_p))
#define Z_BVAL(zval) (zend_bool)(zval).value.lval
#define Z_BVAL_P(zval_p) Z_LVAL(*(zval_p))
#define Z_LVAL(zval) (zval).value.lval
#define Z_LVAL_P(zval_p) Z_LVAL(*(zval_p))
#define Z_DVAL(zval) (zval).value.dval
#define Z_DVAL_P(zval_p) Z_DVAL(*(zval_p))
#define Z_COUNTED(zval) (zval).value.counted
#define Z_COUNTED_P(zval_p) Z_COUNTED(*(zval_p))
#define Z_GC_TYPE(zval) Z_COUNTED(zval)->type
#define Z_GC_TYPE_P(zval_p) Z_GC_TYPE(*(zval_p))
#define Z_GC_BUFFER(zval) Z_COUNTED(zval)->u.v.buffer
#define Z_GC_BUFFER_P(zval_p) Z_GC_BUFFER(*(zval_p))
#define Z_STR(zval) (zval).value.str
#define Z_STR_P(zval_p) Z_STR(*(zval_p))
#define Z_STRVAL(zval) Z_STR(zval)->val
#define Z_STRVAL_P(zval_p) Z_STRVAL(*(zval_p))
#define Z_STRLEN(zval) Z_STR(zval)->len
#define Z_STRLEN_P(zval_p) Z_STRLEN(*(zval_p))
#define Z_STRHASH(zval) Z_STR(zval)->h
#define Z_STRHASH_P(zval_p) Z_STRHASH(*(zval_p))
#define Z_ARR(zval) (zval).value.arr
#define Z_ARR_P(zval_p) Z_ARR(*(zval_p))
#define Z_ARRVAL(zval) (&Z_ARR(zval)->ht)
#define Z_ARRVAL_P(zval_p) Z_ARRVAL(*(zval_p))
#define Z_OBJ(zval) (zval).value.obj
#define Z_OBJ_P(zval_p) Z_OBJ(*(zval_p))
#define Z_OBJ(zval) (zval).value.obj
#define Z_OBJ_P(zval_p) Z_OBJ(*(zval_p))
#define Z_OBJ_HT(zval) Z_OBJ(zval)->handlers
#define Z_OBJ_HT_P(zval_p) Z_OBJ_HT(*(zval_p))
#define Z_OBJ_HANDLER(zval, hf) Z_OBJ_HT((zval))->hf
#define Z_OBJ_HANDLER_P(zv_p, hf) Z_OBJ_HANDLER(*(zv_p), hf)
#define Z_OBJCE(zval) zend_get_class_entry(&(zval) TSRMLS_CC)
#define Z_OBJCE_P(zval_p) Z_OBJCE(*(zval_p))
#define Z_OBJPROP(zval) Z_OBJ_HT((zval))->get_properties(&(zval) TSRMLS_CC)
#define Z_OBJPROP_P(zval_p) Z_OBJPROP(*(zval_p))
#define Z_OBJDEBUG(zval,tmp) (Z_OBJ_HANDLER((zval),get_debug_info)?Z_OBJ_HANDLER((zval),get_debug_info)(&(zval),&tmp TSRMLS_CC):(tmp=0,Z_OBJ_HANDLER((zval),get_properties)?Z_OBJPROP(zval):NULL))
#define Z_OBJDEBUG_P(zval_p,tmp) Z_OBJDEBUG(*(zval_p), tmp)
#define Z_RES(zval) (zval).value.res
#define Z_RES_P(zval_p) Z_RES(*zval_p)
#define Z_RES_HANDLE(zval) Z_RES(zval)->handle
#define Z_RES_HANDLE_P(zval_p) Z_RES_HANDLE(*zval_p)
#define Z_RES_TYPE(zval) Z_RES(zval)->type
#define Z_RES_TYPE_P(zval_p) Z_RES_TYPE(*zval_p)
#define Z_RES_VAL(zval) Z_RES(zval)->ptr
#define Z_RES_VAL_P(zval_p) Z_RES_VAL(*zval_p)
#define Z_REF(zval) (zval).value.ref
#define Z_REF_P(zval_p) Z_REF(*(zval_p))
#define Z_REFVAL(zval) &Z_REF(zval)->val
#define Z_REFVAL_P(zval_p) Z_REFVAL(*(zval_p))
#define Z_AST(zval) (zval).value.ast
#define Z_AST_P(zval_p) Z_AST(*(zval_p))
#define Z_ASTVAL(zval) (zval).value.ast->ast
#define Z_ASTVAL_P(zval_p) Z_ASTVAL(*(zval_p))
#define Z_INDIRECT(zval) (zval).value.zv
#define Z_INDIRECT_P(zval_p) Z_INDIRECT(*(zval_p))
#define Z_CE(zval) (zval).value.ce
#define Z_CE_P(zval_p) Z_CE(*(zval_p))
#define Z_FUNC(zval) (zval).value.func
#define Z_FUNC_P(zval_p) Z_FUNC(*(zval_p))
#define Z_PTR(zval) (zval).value.ptr
#define Z_PTR_P(zval_p) Z_PTR(*(zval_p))
#define Z_STR_OFFSET(zval) (zval).value.str_offset
#define Z_STR_OFFSET_P(zval_p) Z_STR_OFFSET(*(zval_p))
#define ZVAL_UNDEF(z) do { \
Z_TYPE_P(z) = IS_UNDEF; \
} while (0)
#define ZVAL_NULL(z) do { \
Z_TYPE_P(z) = IS_NULL; \
} while (0)
#define ZVAL_BOOL(z, b) do { \
zval *__z = (z); \
Z_LVAL_P(__z) = ((b) != 0); \
Z_TYPE_P(__z) = IS_BOOL; \
} while (0)
#define ZVAL_LONG(z, l) { \
zval *__z = (z); \
Z_LVAL_P(__z) = l; \
Z_TYPE_P(__z) = IS_LONG; \
}
#define ZVAL_DOUBLE(z, d) { \
zval *__z = (z); \
Z_DVAL_P(__z) = d; \
Z_TYPE_P(__z) = IS_DOUBLE; \
}
#define ZVAL_STR(z, s) do { \
zval *__z = (z); \
Z_STR_P(__z) = (s); \
Z_TYPE_P(__z) = IS_STRING; \
} while (0)
#define ZVAL_ARR(z, a) do { \
zval *__z = (z); \
Z_ARR_P(__z) = (a); \
Z_TYPE_P(__z) = IS_ARRAY; \
} while (0)
#define ZVAL_NEW_ARR(z) do { \
zval *__z = (z); \
zend_array *_arr = emalloc(sizeof(zend_array)); \
_arr->gc.refcount = 1; \
_arr->gc.u.v.type = IS_ARRAY; \
_arr->gc.u.v.buffer = 0; \
Z_ARR_P(__z) = _arr; \
Z_TYPE_P(__z) = IS_ARRAY; \
} while (0)
#define ZVAL_NEW_PERSISTENT_ARR(z) do { \
zval *__z = (z); \
zend_array *_arr = malloc(sizeof(zend_array)); \
_arr->gc.refcount = 1; \
_arr->gc.u.v.type = IS_ARRAY; \
_arr->gc.u.v.buffer = 0; \
Z_ARR_P(__z) = _arr; \
Z_TYPE_P(__z) = IS_ARRAY; \
} while (0)
#define ZVAL_OBJ(z, o) do { \
zval *__z = (z); \
Z_OBJ_P(__z) = (o); \
Z_TYPE_P(__z) = IS_OBJECT; \
} while (0)
#define ZVAL_RES(z, r) do { \
zval *__z = (z); \
Z_RES_P(__z) = (r); \
Z_TYPE_P(__z) = IS_RESOURCE; \
} while (0)
#define ZVAL_NEW_RES(z, h, p, t) do { \
zend_resource *_res = emalloc(sizeof(zend_resource)); \
_res->gc.refcount = 1; \
_res->gc.u.v.type = IS_RESOURCE; \
_res->handle = (h); \
_res->type = (t); \
_res->ptr = (p); \
zval *__z = (z); \
Z_RES_P(__z) = _res; \
Z_TYPE_P(__z) = IS_RESOURCE; \
} while (0)
#define ZVAL_NEW_PERSISTENT_RES(z, h, p, t) do { \
zend_resource *_res = malloc(sizeof(zend_resource)); \
_res->gc.refcount = 1; \
_res->gc.u.v.type = IS_RESOURCE; \
_res->handle = (h); \
_res->type = (t); \
_res->ptr = (p); \
zval *__z = (z); \
Z_RES_P(__z) = _res; \
Z_TYPE_P(__z) = IS_RESOURCE; \
} while (0)
#define ZVAL_REF(z, r) do { \
zval *__z = (z); \
Z_REF_P(__z) = (r); \
Z_TYPE_P(__z) = IS_REFERENCE; \
} while (0)
#define ZVAL_NEW_REF(z, r) do { \
zend_reference *_ref = emalloc(sizeof(zend_reference)); \
_ref->gc.refcount = 1; \
_ref->gc.u.v.type = IS_REFERENCE; \
_ref->val = *(r); \
Z_REF_P(z) = _ref; \
Z_TYPE_P(z) = IS_REFERENCE; \
} while (0)
#define ZVAL_NEW_AST(z, a) do { \
zval *__z = (z); \
zend_ast_ref *_ast = emalloc(sizeof(zend_ast_ref)); \
_ast->gc.refcount = 1; \
_ast->gc.u.v.type = IS_CONSTANT_AST; \
_ast->ast = (a); \
Z_AST_P(__z) = _ast; \
Z_TYPE_P(__z) = IS_CONSTANT_AST; \
} while (0)
#define ZVAL_INDIRECT(z, v) do { \
Z_INDIRECT_P(z) = (v); \
Z_TYPE_P(z) = IS_INDIRECT; \
} while (0)
#define ZVAL_PTR(z, p) do { \
Z_PTR_P(z) = (p); \
Z_TYPE_P(z) = IS_PTR; \
} while (0)
#define ZVAL_FUNC(z, f) do { \
Z_FUNC_P(z) = (f); \
Z_TYPE_P(z) = IS_PTR; \
} while (0)
#define ZVAL_CE(z, c) do { \
Z_CE_P(z) = (c); \
Z_TYPE_P(z) = IS_PTR; \
} while (0)
#define ZVAL_STR_OFFSET(z, s, o) do { \
zend_str_offset *x = emalloc(sizeof(zend_str_offset)); \
x->gc.refcount = 1; \
x->gc.u.v.type = IS_STR_OFFSET; \
x->str = (s); \
x->offset = (o); \
Z_STR_OFFSET_P(z) = x; \
Z_TYPE_P(z) = IS_STR_OFFSET; \
} while (0)
#endif /* ZEND_TYPES_H */

View file

@ -27,43 +27,46 @@
#include "zend_constants.h"
#include "zend_list.h"
ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC)
{
switch (Z_TYPE_P(zvalue) & IS_CONSTANT_TYPE_MASK) {
case IS_STRING:
case IS_CONSTANT:
CHECK_ZVAL_STRING_REL(zvalue);
str_efree_rel(zvalue->value.str.val);
STR_FREE(Z_STR_P(zvalue));
break;
case IS_ARRAY:
case IS_CONSTANT_ARRAY: {
TSRMLS_FETCH();
if (zvalue->value.ht && (zvalue->value.ht != &EG(symbol_table))) {
//??? if (zvalue->value.ht && (zvalue->value.ht != &EG(symbol_table))) {
/* break possible cycles */
Z_TYPE_P(zvalue) = IS_NULL;
zend_hash_destroy(zvalue->value.ht);
FREE_HASHTABLE(zvalue->value.ht);
}
zend_hash_destroy(Z_ARRVAL_P(zvalue));
FREE_HASHTABLE(Z_ARR_P(zvalue));
//??? }
}
break;
case IS_CONSTANT_AST:
zend_ast_destroy(Z_AST_P(zvalue));
zend_ast_destroy(Z_AST_P(zvalue)->ast);
break;
case IS_OBJECT:
{
TSRMLS_FETCH();
Z_OBJ_HT_P(zvalue)->del_ref(zvalue TSRMLS_CC);
if (Z_DELREF_P(zvalue) == 0) {
// TODO: release object???
}
}
break;
case IS_RESOURCE:
{
TSRMLS_FETCH();
/* destroy resource */
zend_list_delete(zvalue->value.lval);
if (Z_DELREF_P(zvalue) == 0) {
/* destroy resource */
zend_list_delete(Z_RES_P(zvalue));
}
}
break;
case IS_LONG:
@ -83,7 +86,7 @@ ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC)
case IS_STRING:
case IS_CONSTANT:
CHECK_ZVAL_STRING_REL(zvalue);
str_free(zvalue->value.str.val);
STR_FREE(Z_STR_P(zvalue));
break;
case IS_ARRAY:
case IS_CONSTANT_ARRAY:
@ -102,56 +105,48 @@ ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC)
}
ZEND_API void zval_add_ref(zval **p)
ZEND_API void zval_add_ref(zval *p)
{
Z_ADDREF_PP(p);
if (Z_REFCOUNTED_P(p)) {
Z_ADDREF_P(p);
}
}
ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC)
{
switch (Z_TYPE_P(zvalue) & IS_CONSTANT_TYPE_MASK) {
case IS_RESOURCE: {
TSRMLS_FETCH();
zend_list_addref(zvalue->value.lval);
}
break;
case IS_BOOL:
case IS_LONG:
case IS_NULL:
break;
case IS_CONSTANT:
case IS_STRING:
CHECK_ZVAL_STRING_REL(zvalue);
if (!IS_INTERNED(zvalue->value.str.val)) {
zvalue->value.str.val = (char *) estrndup_rel(zvalue->value.str.val, zvalue->value.str.len);
}
Z_STR_P(zvalue) = STR_DUP(Z_STR_P(zvalue), 0);
break;
case IS_ARRAY:
case IS_CONSTANT_ARRAY: {
zval *tmp;
HashTable *original_ht = zvalue->value.ht;
HashTable *tmp_ht = NULL;
HashTable *ht = Z_ARRVAL_P(zvalue);
TSRMLS_FETCH();
if (zvalue->value.ht == &EG(symbol_table)) {
if (ht == &EG(symbol_table).ht) {
return; /* do nothing */
}
ALLOC_HASHTABLE_REL(tmp_ht);
zend_hash_init(tmp_ht, zend_hash_num_elements(original_ht), NULL, ZVAL_PTR_DTOR, 0);
zend_hash_copy(tmp_ht, original_ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
zvalue->value.ht = tmp_ht;
ZVAL_NEW_ARR(zvalue);
zend_hash_init(Z_ARRVAL_P(zvalue), zend_hash_num_elements(ht), NULL, ZVAL_PTR_DTOR, 0);
zend_hash_copy(Z_ARRVAL_P(zvalue), ht, (copy_ctor_func_t) zval_add_ref);
}
break;
case IS_CONSTANT_AST:
Z_AST_P(zvalue) = zend_ast_copy(Z_AST_P(zvalue));
case IS_CONSTANT_AST: {
zend_ast_ref *ast = emalloc(sizeof(zend_ast_ref));
ast->gc.refcount = 1;
ast->gc.u.v.type = IS_CONSTANT_AST;
ast->ast = zend_ast_copy(Z_ASTVAL_P(zvalue));
Z_AST_P(zvalue) = ast;
}
break;
case IS_OBJECT:
{
TSRMLS_FETCH();
Z_OBJ_HT_P(zvalue)->add_ref(zvalue TSRMLS_CC);
}
case IS_RESOURCE:
case IS_REFERENCE:
Z_ADDREF_P(zvalue);
break;
}
}
@ -185,58 +180,68 @@ ZEND_API void _zval_internal_dtor_wrapper(zval *zvalue)
}
ZEND_API void _zval_ptr_dtor_wrapper(zval **zval_ptr)
ZEND_API void _zval_ptr_dtor_wrapper(zval *zval_ptr)
{
zval_ptr_dtor(zval_ptr);
}
ZEND_API void _zval_internal_ptr_dtor_wrapper(zval **zval_ptr)
ZEND_API void _zval_internal_ptr_dtor_wrapper(zval *zval_ptr)
{
zval_internal_ptr_dtor(zval_ptr);
}
#endif
ZEND_API int zval_copy_static_var(zval **p TSRMLS_DC, int num_args, va_list args, zend_hash_key *key) /* {{{ */
ZEND_API int zval_copy_static_var(zval *p TSRMLS_DC, int num_args, va_list args, zend_hash_key *key) /* {{{ */
{
HashTable *target = va_arg(args, HashTable*);
zend_bool is_ref;
zval *tmp;
zval tmp;
if (Z_TYPE_PP(p) & (IS_LEXICAL_VAR|IS_LEXICAL_REF)) {
is_ref = Z_TYPE_PP(p) & IS_LEXICAL_REF;
if (Z_TYPE_P(p) & (IS_LEXICAL_VAR|IS_LEXICAL_REF)) {
is_ref = Z_TYPE_P(p) & IS_LEXICAL_REF;
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
}
if (zend_hash_quick_find(EG(active_symbol_table), key->arKey, key->nKeyLength, key->h, (void **) &p) == FAILURE) {
if (is_ref) {
ALLOC_INIT_ZVAL(tmp);
Z_SET_ISREF_P(tmp);
zend_hash_quick_add(EG(active_symbol_table), key->arKey, key->nKeyLength, key->h, &tmp, sizeof(zval*), (void**)&p);
p = zend_hash_find(EG(active_symbol_table), key->key);
if (!p) {
p = &tmp;
ZVAL_NULL(&tmp);
if (is_ref) {
ZVAL_NEW_REF(&tmp, &tmp);
zend_hash_add(EG(active_symbol_table), key->key, &tmp);
} else {
tmp = EG(uninitialized_zval_ptr);
zend_error(E_NOTICE,"Undefined variable: %s", key->arKey);
zend_error(E_NOTICE,"Undefined variable: %s", key->key->val);
}
} else {
if (is_ref) {
SEPARATE_ZVAL_TO_MAKE_IS_REF(p);
tmp = *p;
} else if (Z_ISREF_PP(p)) {
ALLOC_INIT_ZVAL(tmp);
ZVAL_COPY_VALUE(tmp, *p);
zval_copy_ctor(tmp);
Z_SET_REFCOUNT_P(tmp, 0);
Z_UNSET_ISREF_P(tmp);
} else {
tmp = *p;
//??? SEPARATE_ZVAL_TO_MAKE_IS_REF(p);
if (!Z_ISREF_P(p)) {
if (IS_REFCOUNTED(Z_TYPE_P(p)) && Z_REFCOUNT_P(p) > 1) {
Z_DELREF_P(p);
ZVAL_NEW_REF(p, p);
zval_copy_ctor(Z_REFVAL_P(p));
Z_SET_REFCOUNT_P(Z_REFVAL_P(p), 1);
} else {
ZVAL_NEW_REF(p, p);
}
}
} else if (Z_ISREF_P(p)) {
//???
tmp = *Z_REFVAL_P(p);
if (Z_REFCOUNTED(tmp) && Z_REFCOUNT(tmp) > 1) {
zval_copy_ctor(&tmp);
Z_SET_REFCOUNT(tmp, 0);
}
p = &tmp;
}
}
} else {
tmp = *p;
}
if (zend_hash_quick_add(target, key->arKey, key->nKeyLength, key->h, &tmp, sizeof(zval*), NULL) == SUCCESS) {
Z_ADDREF_P(tmp);
if (zend_hash_add(target, key->key, p)) {
if (Z_REFCOUNTED_P(p)) {
Z_ADDREF_P(p);
}
}
return ZEND_HASH_APPLY_KEEP;
}

View file

@ -29,7 +29,7 @@ ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC);
static zend_always_inline void _zval_dtor(zval *zvalue ZEND_FILE_LINE_DC)
{
if (zvalue->type <= IS_BOOL) {
if (!Z_REFCOUNTED_P(zvalue)) {
return;
}
_zval_dtor_func(zvalue ZEND_FILE_LINE_RELAY_CC);
@ -39,18 +39,18 @@ ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC);
static zend_always_inline void _zval_copy_ctor(zval *zvalue ZEND_FILE_LINE_DC)
{
if (zvalue->type <= IS_BOOL) {
if (!Z_REFCOUNTED_P(zvalue)) {
return;
}
_zval_copy_ctor_func(zvalue ZEND_FILE_LINE_RELAY_CC);
}
ZEND_API int zval_copy_static_var(zval **p TSRMLS_DC, int num_args, va_list args, zend_hash_key *key);
ZEND_API int zval_copy_static_var(zval *p TSRMLS_DC, int num_args, va_list args, zend_hash_key *key);
ZEND_API int zend_print_variable(zval *var);
ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC);
ZEND_API void _zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC);
ZEND_API void _zval_internal_dtor(zval *zvalue ZEND_FILE_LINE_DC);
ZEND_API void _zval_internal_ptr_dtor(zval **zvalue ZEND_FILE_LINE_DC);
ZEND_API void _zval_internal_ptr_dtor(zval *zvalue ZEND_FILE_LINE_DC);
ZEND_API void _zval_dtor_wrapper(zval *zvalue);
#define zval_copy_ctor(zvalue) _zval_copy_ctor((zvalue) ZEND_FILE_LINE_CC)
#define zval_dtor(zvalue) _zval_dtor((zvalue) ZEND_FILE_LINE_CC)
@ -61,9 +61,9 @@ ZEND_API void _zval_dtor_wrapper(zval *zvalue);
#if ZEND_DEBUG
ZEND_API void _zval_copy_ctor_wrapper(zval *zvalue);
ZEND_API void _zval_ptr_dtor_wrapper(zval **zval_ptr);
ZEND_API void _zval_ptr_dtor_wrapper(zval *zval_ptr);
ZEND_API void _zval_internal_dtor_wrapper(zval *zvalue);
ZEND_API void _zval_internal_ptr_dtor_wrapper(zval **zvalue);
ZEND_API void _zval_internal_ptr_dtor_wrapper(zval *zvalue);
#define zval_copy_ctor_wrapper _zval_copy_ctor_wrapper
#define zval_ptr_dtor_wrapper _zval_ptr_dtor_wrapper
#define zval_internal_dtor_wrapper _zval_internal_dtor_wrapper
@ -75,15 +75,15 @@ ZEND_API void _zval_internal_ptr_dtor_wrapper(zval **zvalue);
#define zval_internal_ptr_dtor_wrapper _zval_internal_ptr_dtor
#endif
ZEND_API void zval_add_ref(zval **p);
ZEND_API void zval_add_ref(zval *p);
END_EXTERN_C()
#define ZVAL_DESTRUCTOR (void (*)(void *)) zval_dtor_wrapper
#define ZVAL_PTR_DTOR (void (*)(void *)) zval_ptr_dtor_wrapper
#define ZVAL_INTERNAL_DTOR (void (*)(void *)) zval_internal_dtor_wrapper
#define ZVAL_INTERNAL_PTR_DTOR (void (*)(void *)) zval_internal_ptr_dtor_wrapper
#define ZVAL_COPY_CTOR (void (*)(void *)) zval_copy_ctor_wrapper
#define ZVAL_DESTRUCTOR zval_dtor_wrapper
#define ZVAL_PTR_DTOR zval_ptr_dtor_wrapper
#define ZVAL_INTERNAL_DTOR zval_internal_dtor_wrapper
#define ZVAL_INTERNAL_PTR_DTOR zval_internal_ptr_dtor_wrapper
#define ZVAL_COPY_CTOR zval_copy_ctor_wrapper
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -38,7 +38,7 @@ zend_vm_enter:
ZEND_API void zend_{%EXECUTOR_NAME%}(zend_op_array *op_array TSRMLS_DC)
{
if (EG(exception)) {
if (EG(exception) != NULL) {
return;
}
zend_{%EXECUTOR_NAME%}_ex(i_create_execute_data_from_op_array(op_array, 0 TSRMLS_CC) TSRMLS_CC);

View file

@ -135,28 +135,6 @@ $op2_get_zval_ptr = array(
"CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var TSRMLS_CC)",
);
$op1_get_zval_ptr_ptr = array(
"ANY" => "get_zval_ptr_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, \\1)",
"TMP" => "NULL",
"VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)",
"CONST" => "NULL",
"UNUSED" => "NULL",
"CV" => "_get_zval_ptr_ptr_cv_\\1(execute_data, opline->op1.var TSRMLS_CC)",
);
$op1_get_zval_ptr_ptr_fast = $op1_get_zval_ptr_ptr;
$op1_get_zval_ptr_ptr_fast["VAR"] = "_get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)";
$op2_get_zval_ptr_ptr = array(
"ANY" => "get_zval_ptr_ptr(opline->op2_type, &opline->op2, execute_data, &free_op2, \\1)",
"TMP" => "NULL",
"VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)",
"CONST" => "NULL",
"UNUSED" => "NULL",
"CV" => "_get_zval_ptr_ptr_cv_\\1(execute_data, opline->op2.var TSRMLS_CC)",
);
$op2_get_zval_ptr_ptr_fast = $op2_get_zval_ptr_ptr;
$op2_get_zval_ptr_ptr_fast["VAR"] = "_get_zval_ptr_ptr_var_fast(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)";
$op1_get_obj_zval_ptr = array(
"ANY" => "get_obj_zval_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, \\1)",
"TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)",
@ -175,28 +153,6 @@ $op2_get_obj_zval_ptr = array(
"CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var TSRMLS_CC)",
);
$op1_get_obj_zval_ptr_ptr = array(
"ANY" => "get_obj_zval_ptr_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, \\1)",
"TMP" => "NULL",
"VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)",
"CONST" => "NULL",
"UNUSED" => "_get_obj_zval_ptr_ptr_unused(TSRMLS_C)",
"CV" => "_get_zval_ptr_ptr_cv_\\1(execute_data, opline->op1.var TSRMLS_CC)",
);
$op1_get_obj_zval_ptr_ptr_fast = $op1_get_obj_zval_ptr_ptr;
$op1_get_obj_zval_ptr_ptr_fast["VAR"] = "_get_zval_ptr_ptr_var_fast(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)";
$op2_get_obj_zval_ptr_ptr = array(
"ANY" => "get_obj_zval_ptr_ptr(opline->op2_type, &opline->op2, execute_data, &free_op2, \\1)",
"TMP" => "NULL",
"VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)",
"CONST" => "NULL",
"UNUSED" => "_get_obj_zval_ptr_ptr_unused(TSRMLS_C)",
"CV" => "_get_zval_ptr_ptr_cv_\\1(execute_data, opline->op2.var TSRMLS_CC)",
);
$op2_get_obj_zval_ptr_ptr_fast = $op2_get_obj_zval_ptr_ptr;
$op2_get_obj_zval_ptr_ptr_fast["VAR"] = "_get_zval_ptr_ptr_var_fast(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)";
$op1_is_tmp_free = array(
"ANY" => "IS_TMP_FREE(free_op1)",
"TMP" => "1",
@ -218,7 +174,7 @@ $op2_is_tmp_free = array(
$op1_free_op = array(
"ANY" => "FREE_OP(free_op1)",
"TMP" => "zval_dtor(free_op1.var)",
"VAR" => "zval_ptr_dtor_nogc(&free_op1.var)",
"VAR" => "zval_ptr_dtor_nogc(free_op1.var)",
"CONST" => "",
"UNUSED" => "",
"CV" => "",
@ -227,7 +183,7 @@ $op1_free_op = array(
$op2_free_op = array(
"ANY" => "FREE_OP(free_op2)",
"TMP" => "zval_dtor(free_op2.var)",
"VAR" => "zval_ptr_dtor_nogc(&free_op2.var)",
"VAR" => "zval_ptr_dtor_nogc(free_op2.var)",
"CONST" => "",
"UNUSED" => "",
"CV" => "",
@ -236,7 +192,7 @@ $op2_free_op = array(
$op1_free_op_if_var = array(
"ANY" => "FREE_OP_IF_VAR(free_op1)",
"TMP" => "",
"VAR" => "zval_ptr_dtor_nogc(&free_op1.var)",
"VAR" => "zval_ptr_dtor_nogc(free_op1.var)",
"CONST" => "",
"UNUSED" => "",
"CV" => "",
@ -245,33 +201,33 @@ $op1_free_op_if_var = array(
$op2_free_op_if_var = array(
"ANY" => "FREE_OP_IF_VAR(free_op2)",
"TMP" => "",
"VAR" => "zval_ptr_dtor_nogc(&free_op2.var)",
"VAR" => "zval_ptr_dtor_nogc(free_op2.var)",
"CONST" => "",
"UNUSED" => "",
"CV" => "",
);
$op1_free_op_var_ptr = array(
"ANY" => "if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}",
"ANY" => "if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}",
"TMP" => "",
"VAR" => "if (free_op1.var) {zval_ptr_dtor_nogc(&free_op1.var);}",
"VAR" => "if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}",
"CONST" => "",
"UNUSED" => "",
"CV" => "",
);
$op1_free_op_var_ptr_fast = $op1_free_op_var_ptr;
$op1_free_op_var_ptr_fast["VAR"] = "zval_ptr_dtor_nogc(&free_op1.var)";
$op1_free_op_var_ptr_fast["VAR"] = "zval_ptr_dtor_nogc(free_op1.var)";
$op2_free_op_var_ptr = array(
"ANY" => "if (free_op2.var) {zval_ptr_dtor_nogc(&free_op2.var);}",
"ANY" => "if (free_op2.var) {zval_ptr_dtor_nogc(free_op2.var);}",
"TMP" => "",
"VAR" => "if (free_op2.var) {zval_ptr_dtor_nogc(&free_op2.var);}",
"VAR" => "if (free_op2.var) {zval_ptr_dtor_nogc(free_op2.var);}",
"CONST" => "",
"UNUSED" => "",
"CV" => "",
);
$op2_free_op_var_ptr_fast = $op2_free_op_var_ptr;
$op2_free_op_var_ptr_fast["VAR"] = "zval_ptr_dtor_nogc(&free_op2.var)";
$op2_free_op_var_ptr_fast["VAR"] = "zval_ptr_dtor_nogc(free_op2.var)";
$list = array(); // list of opcode handlers and helpers in original order
$opcodes = array(); // opcode handlers by code
@ -318,14 +274,10 @@ function helper_name($name, $spec, $op1, $op2) {
// Generates code for opcode handler or helper
function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
global $op1_type, $op2_type, $op1_get_zval_ptr, $op2_get_zval_ptr,
$op1_get_zval_ptr_ptr, $op2_get_zval_ptr_ptr,
$op1_get_obj_zval_ptr, $op2_get_obj_zval_ptr,
$op1_get_obj_zval_ptr_ptr, $op2_get_obj_zval_ptr_ptr,
$op1_is_tmp_free, $op2_is_tmp_free, $op1_free, $op2_free,
$op1_free_op, $op2_free_op, $op1_free_op_if_var, $op2_free_op_if_var,
$op1_free_op_var_ptr, $op2_free_op_var_ptr, $prefix,
$op1_get_zval_ptr_ptr_fast, $op2_get_zval_ptr_ptr_fast,
$op1_get_obj_zval_ptr_ptr_fast, $op2_get_obj_zval_ptr_ptr_fast,
$op1_free_op_var_ptr, $op2_free_op_var_ptr, $prefix,
$op1_free_op_var_ptr_fast, $op2_free_op_var_ptr_fast;
// Specializing
@ -337,12 +289,8 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
"/OP2_FREE/",
"/GET_OP1_ZVAL_PTR\(([^)]*)\)/",
"/GET_OP2_ZVAL_PTR\(([^)]*)\)/",
"/GET_OP1_ZVAL_PTR_PTR\(([^)]*)\)/",
"/GET_OP2_ZVAL_PTR_PTR\(([^)]*)\)/",
"/GET_OP1_OBJ_ZVAL_PTR\(([^)]*)\)/",
"/GET_OP2_OBJ_ZVAL_PTR\(([^)]*)\)/",
"/GET_OP1_OBJ_ZVAL_PTR_PTR\(([^)]*)\)/",
"/GET_OP2_OBJ_ZVAL_PTR_PTR\(([^)]*)\)/",
"/IS_OP1_TMP_FREE\(\)/",
"/IS_OP2_TMP_FREE\(\)/",
"/FREE_OP1\(\)/",
@ -351,10 +299,6 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
"/FREE_OP2_IF_VAR\(\)/",
"/FREE_OP1_VAR_PTR\(\)/",
"/FREE_OP2_VAR_PTR\(\)/",
"/GET_OP1_ZVAL_PTR_PTR_FAST\(([^)]*)\)/",
"/GET_OP2_ZVAL_PTR_PTR_FAST\(([^)]*)\)/",
"/GET_OP1_OBJ_ZVAL_PTR_PTR_FAST\(([^)]*)\)/",
"/GET_OP2_OBJ_ZVAL_PTR_PTR_FAST\(([^)]*)\)/",
"/FREE_OP1_VAR_PTR_FAST\(\)/",
"/FREE_OP2_VAR_PTR_FAST\(\)/",
"/^#ifdef\s+ZEND_VM_SPEC\s*\n/m",
@ -375,12 +319,8 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
$op2_free[$op2],
$op1_get_zval_ptr[$op1],
$op2_get_zval_ptr[$op2],
$op1_get_zval_ptr_ptr[$op1],
$op2_get_zval_ptr_ptr[$op2],
$op1_get_obj_zval_ptr[$op1],
$op2_get_obj_zval_ptr[$op2],
$op1_get_obj_zval_ptr_ptr[$op1],
$op2_get_obj_zval_ptr_ptr[$op2],
$op1_is_tmp_free[$op1],
$op2_is_tmp_free[$op2],
$op1_free_op[$op1],
@ -389,10 +329,6 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
$op2_free_op_if_var[$op2],
$op1_free_op_var_ptr[$op1],
$op2_free_op_var_ptr[$op2],
$op1_get_zval_ptr_ptr_fast[$op1],
$op2_get_zval_ptr_ptr_fast[$op2],
$op1_get_obj_zval_ptr_ptr_fast[$op1],
$op2_get_obj_zval_ptr_ptr_fast[$op2],
$op1_free_op_var_ptr_fast[$op1],
$op2_free_op_var_ptr_fast[$op2],
($op1!="ANY"||$op2!="ANY")?"#if 1\n":"#if 0\n",

View file

@ -350,7 +350,7 @@ PHP_MINIT_FUNCTION(com_dotnet)
php_com_persist_minit(INIT_FUNC_ARGS_PASSTHRU);
INIT_CLASS_ENTRY(ce, "com_exception", NULL);
php_com_exception_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
php_com_exception_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C) TSRMLS_CC);
php_com_exception_class_entry->ce_flags |= ZEND_ACC_FINAL;
/* php_com_exception_class_entry->constructor->common.fn_flags |= ZEND_ACC_PROTECTED; */
@ -367,7 +367,7 @@ PHP_MINIT_FUNCTION(com_dotnet)
INIT_CLASS_ENTRY(ce, "com", NULL);
ce.create_object = php_com_object_new;
tmp = zend_register_internal_class_ex(&ce, php_com_variant_class_entry, "variant" TSRMLS_CC);
tmp = zend_register_internal_class_ex(&ce, php_com_variant_class_entry TSRMLS_CC);
tmp->get_iterator = php_com_iter_get;
zend_ts_hash_init(&php_com_typelibraries, 0, NULL, php_com_typelibrary_dtor, 1);
@ -375,7 +375,7 @@ PHP_MINIT_FUNCTION(com_dotnet)
#if HAVE_MSCOREE_H
INIT_CLASS_ENTRY(ce, "dotnet", NULL);
ce.create_object = php_com_object_new;
tmp = zend_register_internal_class_ex(&ce, php_com_variant_class_entry, "variant" TSRMLS_CC);
tmp = zend_register_internal_class_ex(&ce, php_com_variant_class_entry TSRMLS_CC);
tmp->get_iterator = php_com_iter_get;
#endif

File diff suppressed because it is too large Load diff

View file

@ -671,7 +671,7 @@ PHP_MINIT_FUNCTION(dom)
zend_hash_init(&classes, 0, NULL, NULL, 1);
INIT_CLASS_ENTRY(ce, "DOMException", php_dom_domexception_class_functions);
dom_domexception_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
dom_domexception_class_entry = zend_register_internal_class_ex(&ce, zend_exception_get_default(TSRMLS_C) TSRMLS_CC);
dom_domexception_class_entry->ce_flags |= ZEND_ACC_FINAL;
zend_declare_property_long(dom_domexception_class_entry, "code", sizeof("code")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC);
@ -760,7 +760,7 @@ PHP_MINIT_FUNCTION(dom)
INIT_CLASS_ENTRY(ce, "DOMNodeList", php_dom_nodelist_class_functions);
ce.create_object = dom_nnodemap_objects_new;
dom_nodelist_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
dom_nodelist_class_entry = zend_register_internal_class_ex(&ce, NULL TSRMLS_CC);
dom_nodelist_class_entry->get_iterator = php_dom_get_iterator;
zend_class_implements(dom_nodelist_class_entry TSRMLS_CC, 1, zend_ce_traversable);
@ -770,7 +770,7 @@ PHP_MINIT_FUNCTION(dom)
INIT_CLASS_ENTRY(ce, "DOMNamedNodeMap", php_dom_namednodemap_class_functions);
ce.create_object = dom_nnodemap_objects_new;
dom_namednodemap_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
dom_namednodemap_class_entry = zend_register_internal_class_ex(&ce, NULL TSRMLS_CC);
dom_namednodemap_class_entry->get_iterator = php_dom_get_iterator;
zend_class_implements(dom_namednodemap_class_entry TSRMLS_CC, 1, zend_ce_traversable);
@ -898,7 +898,7 @@ PHP_MINIT_FUNCTION(dom)
#if defined(LIBXML_XPATH_ENABLED)
INIT_CLASS_ENTRY(ce, "DOMXPath", php_dom_xpath_class_functions);
ce.create_object = dom_xpath_objects_new;
dom_xpath_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
dom_xpath_class_entry = zend_register_internal_class_ex(&ce, NULL TSRMLS_CC);
zend_hash_init(&dom_xpath_prop_handlers, 0, NULL, NULL, 1);
dom_register_prop_handler(&dom_xpath_prop_handlers, "document", dom_xpath_document_read, NULL TSRMLS_CC);

View file

@ -127,7 +127,7 @@ int dom_set_doc_classmap(php_libxml_ref_obj *document, zend_class_entry *basece,
#define REGISTER_DOM_CLASS(ce, name, parent_ce, funcs, entry) \
INIT_CLASS_ENTRY(ce, name, funcs); \
ce.create_object = dom_objects_new; \
entry = zend_register_internal_class_ex(&ce, parent_ce, NULL TSRMLS_CC);
entry = zend_register_internal_class_ex(&ce, parent_ce TSRMLS_CC);
#define DOM_GET_OBJ(__ptr, __id, __prtype, __intern) { \
__intern = (dom_object *)zend_object_store_get_object(__id TSRMLS_CC); \

View file

@ -105,14 +105,14 @@ ZEND_GET_MODULE(ereg)
/* {{{ ereg_lru_cmp */
static int ereg_lru_cmp(const void *a, const void *b TSRMLS_DC)
{
Bucket *f = *((Bucket **) a);
Bucket *s = *((Bucket **) b);
Bucket *f = (Bucket *) a;
Bucket *s = (Bucket *) b;
if (((reg_cache *)f->pData)->lastuse <
((reg_cache *)s->pData)->lastuse) {
if (((reg_cache *)Z_PTR(f->val))->lastuse <
((reg_cache *)Z_PTR(s->val))->lastuse) {
return -1;
} else if (((reg_cache *)f->pData)->lastuse ==
((reg_cache *)s->pData)->lastuse) {
} else if (((reg_cache *)Z_PTR(f->val))->lastuse ==
((reg_cache *)Z_PTR(s->val))->lastuse) {
return 0;
} else {
return 1;
@ -121,7 +121,7 @@ static int ereg_lru_cmp(const void *a, const void *b TSRMLS_DC)
/* }}} */
/* {{{ static ereg_clean_cache */
static int ereg_clean_cache(void *data, void *arg TSRMLS_DC)
static int ereg_clean_cache(zval *data, void *arg TSRMLS_DC)
{
int *num_clean = (int *)arg;
@ -153,7 +153,8 @@ static int _php_regcomp(regex_t *preg, const char *pattern, int cflags TSRMLS_DC
}
}
if(zend_hash_find(&EREG(ht_rc), (char *) pattern, patlen+1, (void **) &rc) == SUCCESS
rc = zend_hash_str_find_ptr(&EREG(ht_rc), pattern, patlen);
if (rc
&& rc->cflags == cflags) {
#ifdef HAVE_REGEX_T_RE_MAGIC
/*
@ -182,8 +183,8 @@ static int _php_regcomp(regex_t *preg, const char *pattern, int cflags TSRMLS_DC
* it's good.
*/
if (!reg_magic) reg_magic = preg->re_magic;
zend_hash_update(&EREG(ht_rc), (char *) pattern, patlen+1,
(void *) &rcp, sizeof(rcp), NULL);
zend_hash_str_update_mem(&EREG(ht_rc), pattern, patlen,
&rcp, sizeof(rcp));
}
#else
memcpy(preg, &rc->preg, sizeof(*preg));
@ -195,8 +196,8 @@ static int _php_regcomp(regex_t *preg, const char *pattern, int cflags TSRMLS_DC
rcp.cflags = cflags;
rcp.lastuse = ++(EREG(lru_counter));
memcpy(&rcp.preg, preg, sizeof(*preg));
zend_hash_update(&EREG(ht_rc), (char *) pattern, patlen+1,
(void *) &rcp, sizeof(rcp), NULL);
zend_hash_str_update_mem(&EREG(ht_rc), pattern, patlen,
&rcp, sizeof(rcp));
}
}
#endif
@ -204,8 +205,9 @@ static int _php_regcomp(regex_t *preg, const char *pattern, int cflags TSRMLS_DC
}
/* }}} */
static void _free_ereg_cache(reg_cache *rc)
static void _free_ereg_cache(zval *zv)
{
reg_cache *rc = Z_PTR_P(zv);
regfree(&rc->preg);
}
@ -218,7 +220,7 @@ static void _free_ereg_cache(reg_cache *rc)
*/
static PHP_GINIT_FUNCTION(ereg)
{
zend_hash_init(&ereg_globals->ht_rc, 0, NULL, (void (*)(void *)) _free_ereg_cache, 1);
zend_hash_init(&ereg_globals->ht_rc, 0, NULL, _free_ereg_cache, 1);
ereg_globals->lru_counter = 0;
}
/* }}} */
@ -279,8 +281,8 @@ static void php_ereg_eprint(int err, regex_t *re TSRMLS_DC) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", message);
}
STR_FREE(buf);
STR_FREE(message);
if (buf) efree(buf);
if (message) efree(message);
}
/* }}} */
@ -288,8 +290,8 @@ static void php_ereg_eprint(int err, regex_t *re TSRMLS_DC) {
*/
static void php_ereg(INTERNAL_FUNCTION_PARAMETERS, int icase)
{
zval **regex, /* Regular expression */
**array = NULL; /* Optional register array */
zval *regex, /* Regular expression */
*array = NULL; /* Optional register array */
char *findin; /* String to apply expression to */
int findin_len;
regex_t re;
@ -302,7 +304,7 @@ static void php_ereg(INTERNAL_FUNCTION_PARAMETERS, int icase)
char *string = NULL;
int argc = ZEND_NUM_ARGS();
if (zend_parse_parameters(argc TSRMLS_CC, "Zs|Z", &regex, &findin, &findin_len, &array) == FAILURE) {
if (zend_parse_parameters(argc TSRMLS_CC, "zs|z", &regex, &findin, &findin_len, &array) == FAILURE) {
return;
}
@ -315,16 +317,16 @@ static void php_ereg(INTERNAL_FUNCTION_PARAMETERS, int icase)
}
/* compile the regular expression from the supplied regex */
if (Z_TYPE_PP(regex) == IS_STRING) {
err = regcomp(&re, Z_STRVAL_PP(regex), REG_EXTENDED | copts);
if (Z_TYPE_P(regex) == IS_STRING) {
err = regcomp(&re, Z_STRVAL_P(regex), REG_EXTENDED | copts);
} else {
/* we convert numbers to integers and treat them as a string */
if (Z_TYPE_PP(regex) == IS_DOUBLE) {
if (Z_TYPE_P(regex) == IS_DOUBLE) {
convert_to_long_ex(regex); /* get rid of decimal places */
}
convert_to_string_ex(regex);
/* don't bother doing an extended regex with just a number */
err = regcomp(&re, Z_STRVAL_PP(regex), copts);
err = regcomp(&re, Z_STRVAL_P(regex), copts);
}
if (err) {
@ -354,16 +356,16 @@ static void php_ereg(INTERNAL_FUNCTION_PARAMETERS, int icase)
buf = emalloc(string_len);
zval_dtor(*array); /* start with clean array */
array_init(*array);
zval_dtor(array); /* start with clean array */
array_init(array);
for (i = 0; i <= re.re_nsub; i++) {
start = subs[i].rm_so;
end = subs[i].rm_eo;
if (start != -1 && end > 0 && start < string_len && end < string_len && start < end) {
add_index_stringl(*array, i, string+start, end-start, 1);
add_index_stringl(array, i, string+start, end-start, 1);
} else {
add_index_bool(*array, i, 0);
add_index_bool(array, i, 0);
}
}
efree(buf);
@ -549,62 +551,61 @@ PHP_EREG_API char *php_ereg_replace(const char *pattern, const char *replace, co
*/
static void php_do_ereg_replace(INTERNAL_FUNCTION_PARAMETERS, int icase)
{
zval **arg_pattern,
**arg_replace;
char *pattern, *arg_string;
char *string;
char *replace;
zval *arg_pattern,
*arg_replace;
zend_string *pattern, *arg_string;
zend_string *string;
zend_string *replace;
char *ret;
int arg_string_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZs", &arg_pattern, &arg_replace, &arg_string, &arg_string_len) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzS", &arg_pattern, &arg_replace, &arg_string) == FAILURE) {
return;
}
if (Z_TYPE_PP(arg_pattern) == IS_STRING) {
if (Z_STRVAL_PP(arg_pattern) && Z_STRLEN_PP(arg_pattern)) {
pattern = estrndup(Z_STRVAL_PP(arg_pattern), Z_STRLEN_PP(arg_pattern));
if (Z_TYPE_P(arg_pattern) == IS_STRING) {
if (Z_STRVAL_P(arg_pattern) && Z_STRLEN_P(arg_pattern)) {
pattern = STR_COPY(Z_STR_P(arg_pattern));
} else {
pattern = STR_EMPTY_ALLOC();
}
} else {
convert_to_long_ex(arg_pattern);
pattern = emalloc(2);
pattern[0] = (char) Z_LVAL_PP(arg_pattern);
pattern[1] = '\0';
pattern = STR_ALLOC(1, 0);
pattern->val[0] = (char) Z_LVAL_P(arg_pattern);
pattern->val[1] = '\0';
}
if (Z_TYPE_PP(arg_replace) == IS_STRING) {
if (Z_STRVAL_PP(arg_replace) && Z_STRLEN_PP(arg_replace)) {
replace = estrndup(Z_STRVAL_PP(arg_replace), Z_STRLEN_PP(arg_replace));
if (Z_TYPE_P(arg_replace) == IS_STRING) {
if (Z_STRVAL_P(arg_replace) && Z_STRLEN_P(arg_replace)) {
replace = STR_COPY(Z_STR_P(arg_replace));
} else {
replace = STR_EMPTY_ALLOC();
}
} else {
convert_to_long_ex(arg_replace);
replace = emalloc(2);
replace[0] = (char) Z_LVAL_PP(arg_replace);
replace[1] = '\0';
replace = STR_ALLOC(1, 0);
replace->val[0] = (char) Z_LVAL_P(arg_replace);
replace->val[1] = '\0';
}
if (arg_string && arg_string_len) {
string = estrndup(arg_string, arg_string_len);
if (arg_string) {
string = STR_COPY(arg_string);
} else {
string = STR_EMPTY_ALLOC();
}
/* do the actual work */
ret = php_ereg_replace(pattern, replace, string, icase, 1 TSRMLS_CC);
ret = php_ereg_replace(pattern->val, replace->val, string->val, icase, 1 TSRMLS_CC);
if (ret == (char *) -1) {
RETVAL_FALSE;
} else {
RETVAL_STRING(ret, 1);
STR_FREE(ret);
RETVAL_STRING(ret);
efree(ret);
}
STR_FREE(string);
STR_FREE(replace);
STR_FREE(pattern);
STR_RELEASE(string);
STR_RELEASE(replace);
STR_RELEASE(pattern);
}
/* }}} */
@ -754,7 +755,7 @@ PHP_EREG_API PHP_FUNCTION(sql_regcase)
}
tmp[j] = 0;
RETVAL_STRINGL(tmp, j, 1);
RETVAL_STRINGL(tmp, j);
efree(tmp);
}
/* }}} */

View file

@ -386,12 +386,12 @@ U_CFUNC void breakiterator_register_BreakIterator_class(TSRMLS_D)
INIT_CLASS_ENTRY(ce, "IntlRuleBasedBreakIterator",
RuleBasedBreakIterator_class_functions);
RuleBasedBreakIterator_ce_ptr = zend_register_internal_class_ex(&ce,
BreakIterator_ce_ptr, NULL TSRMLS_CC);
BreakIterator_ce_ptr TSRMLS_CC);
/* Create and register 'CodePointBreakIterator' class. */
INIT_CLASS_ENTRY(ce, "IntlCodePointBreakIterator",
CodePointBreakIterator_class_functions);
CodePointBreakIterator_ce_ptr = zend_register_internal_class_ex(&ce,
BreakIterator_ce_ptr, NULL TSRMLS_CC);
BreakIterator_ce_ptr TSRMLS_CC);
}
/* }}} */

View file

@ -323,7 +323,7 @@ U_CFUNC void breakiterator_register_IntlPartsIterator_class(TSRMLS_D)
/* Create and register 'BreakIterator' class. */
INIT_CLASS_ENTRY(ce, "IntlPartsIterator", IntlPartsIterator_class_functions);
IntlPartsIterator_ce_ptr = zend_register_internal_class_ex(&ce,
IntlIterator_ce_ptr, NULL TSRMLS_CC);
IntlIterator_ce_ptr TSRMLS_CC);
IntlPartsIterator_ce_ptr->create_object = IntlPartsIterator_object_create;
memcpy(&IntlPartsIterator_handlers, &IntlIterator_handlers,

View file

@ -490,7 +490,7 @@ void calendar_register_IntlCalendar_class(TSRMLS_D)
/* Create and register 'IntlGregorianCalendar' class. */
INIT_CLASS_ENTRY(ce, "IntlGregorianCalendar", GregorianCalendar_class_functions);
GregorianCalendar_ce_ptr = zend_register_internal_class_ex(&ce,
Calendar_ce_ptr, NULL TSRMLS_CC);
Calendar_ce_ptr TSRMLS_CC);
if (!GregorianCalendar_ce_ptr) {
//can't happen know without bigger problems before
php_error_docref0(NULL TSRMLS_CC, E_ERROR,

View file

@ -215,8 +215,8 @@ static int collator_compare_func( const void* a, const void* b TSRMLS_DC )
zval *first;
zval *second;
f = *((Bucket **) a);
s = *((Bucket **) b);
f = (Bucket *) a;
s = (Bucket *) b;
first = *((zval **) f->pData);
second = *((zval **) s->pData);

View file

@ -240,7 +240,7 @@ void intl_register_IntlException_class( TSRMLS_D )
/* Create and register 'IntlException' class. */
INIT_CLASS_ENTRY_EX( ce, "IntlException", sizeof( "IntlException" ) - 1, NULL );
IntlException_ce_ptr = zend_register_internal_class_ex( &ce,
default_exception_ce, NULL TSRMLS_CC );
default_exception_ce TSRMLS_CC );
IntlException_ce_ptr->create_object = default_exception_ce->create_object;
}

View file

@ -2176,14 +2176,15 @@ static void php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type,
if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
if (Z_TYPE_P(ctor_params) == IS_ARRAY) {
HashTable *htl = Z_ARRVAL_P(ctor_params);
uint idx;
Bucket *p;
fci.param_count = 0;
fci.params = safe_emalloc(sizeof(zval*), htl->nNumOfElements, 0);
p = htl->pListHead;
while (p != NULL) {
fci.params[fci.param_count++] = (zval**)p->pData;
p = p->pListNext;
for (idx = 0; idx < htl->nNumUsed; idx++) {
p = htl->arData + idx;
if (!p->xData) continue;
fci.params[fci.param_count++] = (zval**)&p->xData;
}
} else {
/* Two problems why we throw exceptions here: PHP is typeless

View file

@ -634,9 +634,9 @@ PHP_MINIT_FUNCTION(mysqli)
INIT_CLASS_ENTRY(cex, "mysqli_sql_exception", mysqli_exception_methods);
#ifdef HAVE_SPL
mysqli_exception_class_entry = zend_register_internal_class_ex(&cex, spl_ce_RuntimeException, NULL TSRMLS_CC);
mysqli_exception_class_entry = zend_register_internal_class_ex(&cex, spl_ce_RuntimeException TSRMLS_CC);
#else
mysqli_exception_class_entry = zend_register_internal_class_ex(&cex, zend_exception_get_default(TSRMLS_C), NULL TSRMLS_CC);
mysqli_exception_class_entry = zend_register_internal_class_ex(&cex, zend_exception_get_default(TSRMLS_C) TSRMLS_CC);
#endif
mysqli_exception_class_entry->ce_flags |= ZEND_ACC_FINAL;
zend_declare_property_long(mysqli_exception_class_entry, "code", sizeof("code")-1, 0, ZEND_ACC_PROTECTED TSRMLS_CC);
@ -1290,14 +1290,15 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
if (Z_TYPE_P(ctor_params) == IS_ARRAY) {
HashTable *params_ht = Z_ARRVAL_P(ctor_params);
uint idx;
Bucket *p;
fci.param_count = 0;
fci.params = safe_emalloc(sizeof(zval*), params_ht->nNumOfElements, 0);
p = params_ht->pListHead;
while (p != NULL) {
fci.params[fci.param_count++] = (zval**)p->pData;
p = p->pListNext;
for (idx = 0; idx < params_ht->nNumUsed; idx++) {
p = params_ht->arData + idx;
if (!p->xData) continue;
fci.params[fci.param_count++] = (zval**)&p->xData;
}
} else {
/* Two problems why we throw exceptions here: PHP is typeless

View file

@ -173,16 +173,18 @@ PHPAPI void _mysqlnd_plugin_apply_with_argument(apply_func_arg_t apply_func, voi
* zend_hash_apply_with_argument nor zend_hash_internal_pointer_reset and
* friends
*/
uint idx;
Bucket *p;
int result;
p = mysqlnd_registered_plugins.pListHead;
while (p != NULL) {
int result = apply_func(p->pData, argument TSRMLS_CC);
for (idx = 0; idx < mysqlnd_registered_plugins.nNumUsed; idx++) {
p = mysqlnd_registered_plugins.arData + idx;
if (!p->xData) continue;
result = apply_func(HASH_DATA(&mysqlnd_registered_plugins, p), argument TSRMLS_CC);
if (result & ZEND_HASH_APPLY_REMOVE) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "mysqlnd_plugin_apply_with_argument must not remove table entries");
}
p = p->pListNext;
if (result & ZEND_HASH_APPLY_STOP) {
break;
}

View file

@ -60,7 +60,7 @@ mysqlnd_reverse_api_get_api_list(TSRMLS_D)
PHPAPI void
mysqlnd_reverse_api_register_api(MYSQLND_REVERSE_API * apiext TSRMLS_DC)
{
zend_hash_add(&mysqlnd_api_ext_ht, apiext->module->name, strlen(apiext->module->name) + 1, &apiext,
zend_hash_add(&mysqlnd_api_ext_ht, apiext->module->name, strlen(apiext->module->name) + 1, apiext,
sizeof(MYSQLND_REVERSE_API), NULL);
}
/* }}} */

View file

@ -107,17 +107,17 @@ static void
mysqlnd_minfo_dump_api_plugins(smart_str * buffer TSRMLS_DC)
{
HashTable *ht = mysqlnd_reverse_api_get_api_list(TSRMLS_C);
uint idx;
Bucket *p;
p = ht->pListHead;
while(p != NULL) {
MYSQLND_REVERSE_API * ext = *(MYSQLND_REVERSE_API **) p->pData;
for (idx = 0; idx < ht->nNumUsed; idx++) {
p = ht->arData + idx;
if (!p->xData) continue;
MYSQLND_REVERSE_API * ext = (MYSQLND_REVERSE_API *) p->xData;
if (buffer->len) {
smart_str_appendc(buffer, ',');
}
smart_str_appends(buffer, ext->module->name);
p = p->pListNext;
}
}
/* }}} */

View file

@ -283,6 +283,7 @@ static void optimizer_compact_literals(zend_op_array *op_array TSRMLS_DC)
/* Merge equal constants */
j = 0; cache_slots = 0;
zend_hash_init(&hash, 16, NULL, NULL, 0);
hash.flags |= HASH_FLAG_BIG_DATA;
map = (int*)ecalloc(op_array->last_literal, sizeof(int));
for (i = 0; i < op_array->last_literal; i++) {
if (!info[i].flags) {

View file

@ -544,24 +544,29 @@ static void zend_accel_optimize(zend_op_array *op_array,
int zend_accel_script_optimize(zend_persistent_script *script TSRMLS_DC)
{
uint idx, j;
Bucket *p, *q;
HashTable *constants = NULL;
zend_class_entry *ce;
zend_op_array *op_array;
zend_accel_optimize(&script->main_op_array, script, &constants TSRMLS_CC);
p = script->function_table.pListHead;
while (p) {
zend_op_array *op_array = (zend_op_array*)p->pData;
for (idx = 0; idx < script->function_table.nNumUsed; idx++) {
p = script->function_table.arData + idx;
if (!p->xData) continue;
op_array = (zend_op_array*)p->xData;
zend_accel_optimize(op_array, script, &constants TSRMLS_CC);
p = p->pListNext;
}
p = script->class_table.pListHead;
while (p) {
zend_class_entry *ce = (zend_class_entry*)p->pDataPtr;
q = ce->function_table.pListHead;
while (q) {
zend_op_array *op_array = (zend_op_array*)q->pData;
for (idx = 0; idx < script->class_table.nNumUsed; idx++) {
p = script->class_table.arData + idx;
if (!p->xData) continue;
ce = (zend_class_entry*)p->xData;
for (j = 0; j < ce->function_table.nNumUsed; j++) {
q = ce->function_table.arData + j;
if (!q->xData) continue;
op_array = (zend_op_array*)q->xData;
if (op_array->scope == ce) {
zend_accel_optimize(op_array, script, &constants TSRMLS_CC);
} else if (op_array->type == ZEND_USER_FUNCTION) {
@ -572,9 +577,7 @@ int zend_accel_script_optimize(zend_persistent_script *script TSRMLS_DC)
op_array->static_variables = ht;
}
}
q = q->pListNext;
}
p = p->pListNext;
}
if (constants) {

View file

@ -277,35 +277,34 @@ static void accel_interned_strings_restore_for_php(TSRMLS_D)
#ifndef ZTS
static void accel_interned_strings_restore_state(TSRMLS_D)
{
unsigned int i;
uint idx = ZCSG(interned_strings).nNumUsed;
uint nIndex;
Bucket *p;
for (i = 0; i < ZCSG(interned_strings).nTableSize; i++) {
ZCSG(interned_strings).arBuckets[i] = ZCSG(interned_strings_saved_state).arBuckets[i];
if (ZCSG(interned_strings).arBuckets[i]) {
ZCSG(interned_strings).arBuckets[i]->pLast = NULL;
}
ZCSG(interned_strings_top) = ZCSG(interned_strings_saved_top);
while (idx > 0) {
idx--;
p = ZCSG(interned_strings).arData + idx;
if ((char*)p->xData < ZCSG(interned_strings_top)) break;
ZCSG(interned_strings).nNumUsed--;
ZCSG(interned_strings).nNumOfElements--;
nIndex = p->h & ZCSG(interned_strings).nTableMask;
if (ZCSG(interned_strings).arHash[nIndex].idx == idx) {
ZCSG(interned_strings).arHash[nIndex].idx = p->next;
} else {
uint prev = ZCSG(interned_strings).arHash[nIndex].idx;
while (ZCSG(interned_strings).arData[prev].next != idx) {
prev = ZCSG(interned_strings).arData[prev].next;
}
ZCSG(interned_strings).arData[prev].next = p->next;
}
}
ZCSG(interned_strings).pListHead = ZCSG(interned_strings_saved_state).pListHead;
ZCSG(interned_strings).pListTail = ZCSG(interned_strings_saved_state).pListTail;
if (ZCSG(interned_strings).pListHead) {
ZCSG(interned_strings).pListHead->pListLast = NULL;
}
if (ZCSG(interned_strings).pListTail) {
ZCSG(interned_strings).pListTail->pListNext = NULL;
}
ZCSG(interned_strings_top) = ZCSG(interned_strings_saved_state).top;
}
static void accel_interned_strings_save_state(TSRMLS_D)
{
ZCSG(interned_strings_saved_state).arBuckets = (Bucket**)zend_shared_alloc(ZCSG(interned_strings).nTableSize * sizeof(Bucket *));
if (!ZCSG(interned_strings_saved_state).arBuckets) {
zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared memory!");
}
memcpy(ZCSG(interned_strings_saved_state).arBuckets, ZCSG(interned_strings).arBuckets, ZCSG(interned_strings).nTableSize * sizeof(Bucket *));
ZCSG(interned_strings_saved_state).pListHead = ZCSG(interned_strings).pListHead;
ZCSG(interned_strings_saved_state).pListTail = ZCSG(interned_strings).pListTail;
ZCSG(interned_strings_saved_state).top = ZCSG(interned_strings_top);
ZCSG(interned_strings_saved_top) = ZCSG(interned_strings_top);
}
#endif
@ -315,7 +314,9 @@ const char *accel_new_interned_string(const char *arKey, int nKeyLength, int fre
#ifndef ZTS
ulong h;
uint nIndex;
uint idx;
Bucket *p;
zend_string_info *info;
if (arKey >= ZCSG(interned_strings_start) && arKey < ZCSG(interned_strings_end)) {
/* this is already an interned string */
@ -326,8 +327,9 @@ const char *accel_new_interned_string(const char *arKey, int nKeyLength, int fre
nIndex = h & ZCSG(interned_strings).nTableMask;
/* check for existing interned string */
p = ZCSG(interned_strings).arBuckets[nIndex];
while (p != NULL) {
idx = ZCSG(interned_strings).arHash[nIndex].idx;
while (idx != INVALID_IDX) {
p = ZCSG(interned_strings).arData + idx;
if ((p->h == h) && (p->nKeyLength == (uint)nKeyLength)) {
if (!memcmp(p->arKey, arKey, nKeyLength)) {
if (free_src) {
@ -336,7 +338,7 @@ const char *accel_new_interned_string(const char *arKey, int nKeyLength, int fre
return p->arKey;
}
}
p = p->pNext;
idx = p->next;
}
if (ZCSG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength) >=
@ -346,34 +348,19 @@ const char *accel_new_interned_string(const char *arKey, int nKeyLength, int fre
}
/* create new interning string in shared interned strings buffer */
p = (Bucket *) ZCSG(interned_strings_top);
ZCSG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength);
p->arKey = (char*)(p + 1);
memcpy((char*)p->arKey, arKey, nKeyLength);
p->nKeyLength = nKeyLength;
p->h = h;
p->pData = &p->pDataPtr;
p->pDataPtr = p;
p->pNext = ZCSG(interned_strings).arBuckets[nIndex];
p->pLast = NULL;
if (p->pNext) {
p->pNext->pLast = p;
}
ZCSG(interned_strings).arBuckets[nIndex] = p;
p->pListLast = ZCSG(interned_strings).pListTail;
ZCSG(interned_strings).pListTail = p;
p->pListNext = NULL;
if (p->pListLast != NULL) {
p->pListLast->pListNext = p;
}
if (!ZCSG(interned_strings).pListHead) {
ZCSG(interned_strings).pListHead = p;
}
info = (zend_string_info *) ZCSG(interned_strings_top);
ZCSG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(zend_string_info) + nKeyLength);
memcpy((char*)(info + 1), arKey, nKeyLength);
idx = ZCSG(interned_strings).nNumUsed++;
ZCSG(interned_strings).nNumOfElements++;
p = ZCSG(interned_strings).arData + idx;
p->xData = info + 1;
p->h = h;
p->nKeyLength = nKeyLength;
p->next = ZCSG(interned_strings).arHash[nIndex].idx;
ZCSG(interned_strings).arHash[nIndex].idx = idx;
p->arKey = (const char*)(info + 1);
if (free_src) {
efree((char*)arKey);
@ -389,6 +376,7 @@ const char *accel_new_interned_string(const char *arKey, int nKeyLength, int fre
/* Copy PHP interned strings from PHP process memory into the shared memory */
static void accel_use_shm_interned_strings(TSRMLS_D)
{
uint idx, j;
Bucket *p, *q;
#if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO
@ -397,18 +385,19 @@ static void accel_use_shm_interned_strings(TSRMLS_D)
#endif
/* function table hash keys */
p = CG(function_table)->pListHead;
while (p) {
for (idx = 0; idx < CG(function_table)->nNumUsed; idx++) {
p = CG(function_table)->arData + idx;
if (!p->xData) continue;
if (p->nKeyLength) {
p->arKey = accel_new_interned_string(p->arKey, p->nKeyLength, 0 TSRMLS_CC);
}
p = p->pListNext;
}
/* class table hash keys, class names, properties, methods, constants, etc */
p = CG(class_table)->pListHead;
while (p) {
zend_class_entry *ce = (zend_class_entry*)(p->pDataPtr);
for (idx = 0; idx < CG(class_table)->nNumUsed; idx++) {
p = CG(class_table)->arData + idx;
if (!p->xData) continue;
zend_class_entry *ce = (zend_class_entry*)(p->xData);
if (p->nKeyLength) {
p->arKey = accel_new_interned_string(p->arKey, p->nKeyLength, 0 TSRMLS_CC);
@ -418,59 +407,62 @@ static void accel_use_shm_interned_strings(TSRMLS_D)
ce->name = accel_new_interned_string(ce->name, ce->name_length + 1, 0 TSRMLS_CC);
}
q = ce->properties_info.pListHead;
while (q) {
zend_property_info *info = (zend_property_info*)(q->pData);
for (j = 0; j < ce->properties_info.nNumUsed; j++) {
zend_property_info *info;
if (q->nKeyLength) {
q = ce->properties_info.arData + j;
if (!q->xData) continue;
info = (zend_property_info*)(q->xData);
if (q->nKeyLength) {
q->arKey = accel_new_interned_string(q->arKey, q->nKeyLength, 0 TSRMLS_CC);
}
if (info->name) {
info->name = accel_new_interned_string(info->name, info->name_length + 1, 0 TSRMLS_CC);
}
q = q->pListNext;
}
q = ce->function_table.pListHead;
while (q) {
for (j = 0; j < ce->function_table.nNumUsed; j++) {
q = ce->function_table.arData + j;
if (!q->xData) continue;
if (q->nKeyLength) {
q->arKey = accel_new_interned_string(q->arKey, q->nKeyLength, 0 TSRMLS_CC);
}
q = q->pListNext;
}
q = ce->constants_table.pListHead;
while (q) {
for (j = 0; j < ce->constants_table.nNumUsed; j++) {
q = ce->constants_table.arData + j;
if (!q->xData) continue;
if (q->nKeyLength) {
q->arKey = accel_new_interned_string(q->arKey, q->nKeyLength, 0 TSRMLS_CC);
}
q = q->pListNext;
}
p = p->pListNext;
}
/* constant hash keys */
p = EG(zend_constants)->pListHead;
while (p) {
for (idx = 0; idx < EG(zend_constants)->nNumUsed; idx++) {
p = EG(zend_constants)->arData + idx;
if (!p->xData) continue;
if (p->nKeyLength) {
p->arKey = accel_new_interned_string(p->arKey, p->nKeyLength, 0 TSRMLS_CC);
}
p = p->pListNext;
}
/* auto globals hash keys and names */
p = CG(auto_globals)->pListHead;
while (p) {
zend_auto_global *auto_global = (zend_auto_global*)p->pData;
for (idx = 0; idx < CG(auto_globals)->nNumUsed; idx++) {
zend_auto_global *auto_global;
p = CG(auto_globals)->arData + idx;
if (!p->xData) continue;
auto_global = (zend_auto_global*)p->xData;
auto_global->name = accel_new_interned_string(auto_global->name, auto_global->name_len + 1, 0 TSRMLS_CC);
if (p->nKeyLength) {
p->arKey = accel_new_interned_string(p->arKey, p->nKeyLength, 0 TSRMLS_CC);
}
p = p->pListNext;
}
}
#endif
@ -2190,11 +2182,13 @@ static void accel_activate(void)
static void accel_fast_hash_destroy(HashTable *ht)
{
Bucket *p = ht->pListHead;
while (p != NULL) {
ht->pDestructor(p->pData);
p = p->pListNext;
uint idx;
Bucket *p;
for (idx = 0; idx < ht->nNumUsed; idx++) {
p = ht->arData + idx;
if (!p->xData) continue;
ht->pDestructor(&p->xData);
}
}
@ -2473,12 +2467,14 @@ static int zend_accel_init_shm(TSRMLS_D)
zend_hash_init(&ZCSG(interned_strings), (ZCG(accel_directives).interned_strings_buffer * 1024 * 1024) / (sizeof(Bucket) + sizeof(Bucket*) + 8 /* average string length */), NULL, NULL, 1);
if (ZCG(accel_directives).interned_strings_buffer) {
ZCSG(interned_strings).nTableMask = ZCSG(interned_strings).nTableSize - 1;
ZCSG(interned_strings).arBuckets = zend_shared_alloc(ZCSG(interned_strings).nTableSize * sizeof(Bucket *));
ZCSG(interned_strings).arData = zend_shared_alloc(ZCSG(interned_strings).nTableSize * sizeof(Bucket));
ZCSG(interned_strings).arHash = (HashBucket*)zend_shared_alloc(ZCSG(interned_strings).nTableSize * sizeof(HashBucket));
ZCSG(interned_strings_start) = zend_shared_alloc((ZCG(accel_directives).interned_strings_buffer * 1024 * 1024));
if (!ZCSG(interned_strings).arBuckets || !ZCSG(interned_strings_start)) {
if (!ZCSG(interned_strings).arData || !ZCSG(interned_strings_start)) {
zend_accel_error(ACCEL_LOG_FATAL, ACCELERATOR_PRODUCT_NAME " cannot allocate buffer for interned strings");
return FAILURE;
}
memset(ZCSG(interned_strings).arHash, INVALID_IDX, ZCSG(interned_strings).nTableSize * sizeof(HashBucket));
ZCSG(interned_strings_end) = ZCSG(interned_strings_start) + (ZCG(accel_directives).interned_strings_buffer * 1024 * 1024);
ZCSG(interned_strings_top) = ZCSG(interned_strings_start);

View file

@ -303,13 +303,8 @@ typedef struct _zend_accel_shared_globals {
char *interned_strings_start;
char *interned_strings_top;
char *interned_strings_end;
char *interned_strings_saved_top;
HashTable interned_strings;
struct {
Bucket **arBuckets;
Bucket *pListHead;
Bucket *pListTail;
char *top;
} interned_strings_saved_state;
#endif
} zend_accel_shared_globals;

View file

@ -42,7 +42,7 @@ typedef int (*id_function_t)(void *, void *);
typedef void (*unique_copy_ctor_func_t)(void *pElement);
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
static const Bucket *uninitialized_bucket = NULL;
static const HashBucket uninitialized_bucket = {INVALID_IDX};
#endif
static int zend_prepare_function_for_execution(zend_op_array *op_array);
@ -89,10 +89,13 @@ zend_persistent_script* create_persistent_script(void)
static int compact_hash_table(HashTable *ht)
{
uint i = 3;
uint j;
uint nSize;
Bucket **t;
Bucket *d;
HashBucket *h;
Bucket *p;
if (!ht->nNumOfElements) {
if (!ht->nNumOfElements || (ht->flags & HASH_FLAG_PACKED)) {
/* Empty tables don't allocate space for Buckets */
return 1;
}
@ -112,14 +115,25 @@ static int compact_hash_table(HashTable *ht)
return 1;
}
t = (Bucket **)pemalloc(nSize * sizeof(Bucket *), ht->persistent);
if (!t) {
d = (Bucket *)pemalloc(nSize * sizeof(Bucket), ht->flags & HASH_FLAG_PERSISTENT);
h = (HashBucket *)pemalloc(nSize * sizeof(HashBucket), ht->flags & HASH_FLAG_PERSISTENT);
if (!d || !h) {
return 0;
}
pefree(ht->arBuckets, ht->persistent);
for (i = 0, j = 0; i < ht->nNumUsed; i++) {
p = ht->arData + i;
if (p->xData) {
d[j++] = *p;
}
}
ht->nNumUsed = j;
ht->arBuckets = t;
pefree(ht->arData, ht->flags & HASH_FLAG_PERSISTENT);
pefree(ht->arHash, ht->flags & HASH_FLAG_PERSISTENT);
ht->arData = d;
ht->arHash = h;
ht->nTableSize = nSize;
ht->nTableMask = ht->nTableSize - 1;
zend_hash_rehash(ht);
@ -317,114 +331,104 @@ static inline zval* zend_clone_zval(zval *src, int bind TSRMLS_DC)
static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind)
{
Bucket *p, *q, **prev;
uint idx;
Bucket *p, *q;
ulong nIndex;
zval *ppz;
TSRMLS_FETCH();
ht->nTableSize = source->nTableSize;
ht->nTableMask = source->nTableMask;
ht->nNumUsed = 0;
ht->nNumOfElements = source->nNumOfElements;
ht->nNextFreeElement = source->nNextFreeElement;
ht->pDestructor = ZVAL_PTR_DTOR;
#if ZEND_DEBUG
ht->inconsistent = 0;
#endif
ht->persistent = 0;
ht->arBuckets = NULL;
ht->pListHead = NULL;
ht->pListTail = NULL;
ht->pInternalPointer = NULL;
ht->flags = HASH_FLAG_APPLY_PROTECTION | HASH_FLAG_PTR_DATA;
ht->arData = NULL;
ht->arHash = NULL;
ht->nInternalPointer = source->nNumOfElements ? 0 : INVALID_IDX;
ht->nApplyCount = 0;
ht->bApplyProtection = 1;
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
if (!ht->nTableMask) {
ht->arBuckets = (Bucket**)&uninitialized_bucket;
ht->arHash = (HashBucket*)&uninitialized_bucket;
return;
}
#endif
ht->arBuckets = (Bucket **) ecalloc(ht->nTableSize, sizeof(Bucket *));
ht->arData = (Bucket *) ecalloc(ht->nTableSize, sizeof(Bucket));
if (source->flags & HASH_FLAG_PACKED) {
ht->flags |= HASH_FLAG_PACKED;
ht->arHash = (HashBucket*)&uninitialized_bucket;
} else {
ht->arHash = (HashBucket *) ecalloc(ht->nTableSize, sizeof(HashBucket));
memset(ht->arHash, INVALID_IDX, sizeof(HashBucket) * ht->nTableSize);
}
prev = &ht->pListHead;
p = source->pListHead;
while (p) {
for (idx = 0; idx < source->nNumUsed; idx++) {
p = source->arData + idx;
if (!p->xData) continue;
nIndex = p->h & ht->nTableMask;
/* Create bucket and initialize key */
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
if (!p->nKeyLength) {
q = (Bucket *) emalloc(sizeof(Bucket));
q->arKey = NULL;
} else if (IS_INTERNED(p->arKey)) {
q = (Bucket *) emalloc(sizeof(Bucket));
q->arKey = p->arKey;
/* Insert into hash collision list */
if (source->flags & HASH_FLAG_PACKED) {
q = ht->arData + p->h;
ht->nNumUsed = p->h + 1;
} else {
q = (Bucket *) emalloc(sizeof(Bucket) + p->nKeyLength);
q->arKey = ((char*)q) + sizeof(Bucket);
memcpy((char*)q->arKey, p->arKey, p->nKeyLength);
q = ht->arData + ht->nNumUsed;
q->next = ht->arHash[nIndex].idx;
ht->arHash[nIndex].idx = ht->nNumUsed++;
}
#else
q = (Bucket *) emalloc(sizeof(Bucket) - 1 + p->nKeyLength);
if (p->nKeyLength) {
memcpy(q->arKey, p->arKey, p->nKeyLength);
}
#endif
/* Initialize key */
q->h = p->h;
q->nKeyLength = p->nKeyLength;
/* Insert into hash collision list */
q->pNext = ht->arBuckets[nIndex];
q->pLast = NULL;
if (q->pNext) {
q->pNext->pLast = q;
if (!p->nKeyLength) {
q->arKey = NULL;
} else if (IS_INTERNED(p->arKey)) {
q->arKey = p->arKey;
} else {
q->arKey = (const char *) emalloc(p->nKeyLength);
memcpy((char*)q->arKey, p->arKey, p->nKeyLength);
}
ht->arBuckets[nIndex] = q;
/* Insert into global list */
q->pListLast = ht->pListTail;
ht->pListTail = q;
q->pListNext = NULL;
*prev = q;
prev = &q->pListNext;
/* Copy data */
q->pData = &q->pDataPtr;
if (!bind) {
ALLOC_ZVAL(ppz);
*ppz = *((zval*)p->pDataPtr);
*ppz = *((zval*)p->xData);
INIT_PZVAL(ppz);
} else if (Z_REFCOUNT_P((zval*)p->pDataPtr) == 1) {
} else if (Z_REFCOUNT_P((zval*)p->xData) == 1) {
ALLOC_ZVAL(ppz);
*ppz = *((zval*)p->pDataPtr);
} else if (accel_xlat_get(p->pDataPtr, ppz) != SUCCESS) {
*ppz = *((zval*)p->xData);
} else if (accel_xlat_get(p->xData, ppz) != SUCCESS) {
ALLOC_ZVAL(ppz);
*ppz = *((zval*)p->pDataPtr);
accel_xlat_set(p->pDataPtr, ppz);
*ppz = *((zval*)p->xData);
accel_xlat_set(p->xData, ppz);
} else {
q->pDataPtr = *(void**)ppz;
p = p->pListNext;
q->xData = *(void**)ppz;
continue;
}
q->pDataPtr = (void*)ppz;
q->xData = (void*)ppz;
#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
if ((Z_TYPE_P((zval*)p->pDataPtr) & IS_CONSTANT_TYPE_MASK) >= IS_ARRAY) {
switch ((Z_TYPE_P((zval*)p->pDataPtr) & IS_CONSTANT_TYPE_MASK)) {
if ((Z_TYPE_P((zval*)p->xData) & IS_CONSTANT_TYPE_MASK) >= IS_ARRAY) {
switch ((Z_TYPE_P((zval*)p->xData) & IS_CONSTANT_TYPE_MASK)) {
#else
if ((Z_TYPE_P((zval*)p->pDataPtr) & ~IS_CONSTANT_INDEX) >= IS_ARRAY) {
switch ((Z_TYPE_P((zval*)p->pDataPtr) & ~IS_CONSTANT_INDEX)) {
if ((Z_TYPE_P((zval*)p->xData) & ~IS_CONSTANT_INDEX) >= IS_ARRAY) {
switch ((Z_TYPE_P((zval*)p->xData) & ~IS_CONSTANT_INDEX)) {
#endif
case IS_STRING:
case IS_CONSTANT:
Z_STRVAL_P(ppz) = (char *) interned_estrndup(Z_STRVAL_P((zval*)p->pDataPtr), Z_STRLEN_P((zval*)p->pDataPtr));
Z_STRVAL_P(ppz) = (char *) interned_estrndup(Z_STRVAL_P((zval*)p->xData), Z_STRLEN_P((zval*)p->xData));
break;
case IS_ARRAY:
case IS_CONSTANT_ARRAY:
if (((zval*)p->pDataPtr)->value.ht && ((zval*)p->pDataPtr)->value.ht != &EG(symbol_table)) {
if (((zval*)p->xData)->value.ht && ((zval*)p->xData)->value.ht != &EG(symbol_table)) {
ALLOC_HASHTABLE(ppz->value.ht);
zend_hash_clone_zval(ppz->value.ht, ((zval*)p->pDataPtr)->value.ht, 0);
zend_hash_clone_zval(ppz->value.ht, ((zval*)p->xData)->value.ht, 0);
}
break;
#if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO
@ -434,15 +438,13 @@ static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind)
#endif
}
}
p = p->pListNext;
}
ht->pInternalPointer = ht->pListHead;
}
static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class_entry *old_ce, zend_class_entry *ce TSRMLS_DC)
{
Bucket *p, *q, **prev;
uint idx;
Bucket *p, *q;
ulong nIndex;
zend_class_entry **new_ce;
zend_function** new_prototype;
@ -450,80 +452,70 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class
ht->nTableSize = source->nTableSize;
ht->nTableMask = source->nTableMask;
ht->nNumUsed = 0;
ht->nNumOfElements = source->nNumOfElements;
ht->nNextFreeElement = source->nNextFreeElement;
ht->pDestructor = ZEND_FUNCTION_DTOR;
#if ZEND_DEBUG
ht->inconsistent = 0;
#endif
ht->persistent = 0;
ht->pListHead = NULL;
ht->pListTail = NULL;
ht->pInternalPointer = NULL;
ht->flags = HASH_FLAG_APPLY_PROTECTION | HASH_FLAG_BIG_DATA;
ht->nInternalPointer = source->nNumOfElements ? 0 : INVALID_IDX;
ht->nApplyCount = 0;
ht->bApplyProtection = 1;
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
if (!ht->nTableMask) {
ht->arBuckets = (Bucket**)&uninitialized_bucket;
ht->arHash = (HashBucket*)&uninitialized_bucket;
return;
}
#endif
ht->arBuckets = (Bucket **) ecalloc(ht->nTableSize, sizeof(Bucket *));
ht->arData = (Bucket *) ecalloc(ht->nTableSize, sizeof(Bucket));
if (source->flags & HASH_FLAG_PACKED) {
ht->flags |= HASH_FLAG_PACKED;
ht->arHash = (HashBucket*)&uninitialized_bucket;
} else {
ht->arHash = (HashBucket *) ecalloc(ht->nTableSize, sizeof(HashBucket));
memset(ht->arHash, INVALID_IDX, sizeof(HashBucket) * ht->nTableSize);
}
for (idx = 0; idx < source->nNumUsed; idx++) {
p = source->arData + idx;
if (!p->xData) continue;
prev = &ht->pListHead;
p = source->pListHead;
while (p) {
nIndex = p->h & ht->nTableMask;
/* Create bucket and initialize key */
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
if (!p->nKeyLength) {
q = (Bucket *) emalloc(sizeof(Bucket));
q->arKey = NULL;
} else if (IS_INTERNED(p->arKey)) {
q = (Bucket *) emalloc(sizeof(Bucket));
q->arKey = p->arKey;
/* Insert into hash collision list */
if (source->flags & HASH_FLAG_PACKED) {
q = ht->arData + p->h;
ht->nNumUsed = p->h + 1;
} else {
q = (Bucket *) emalloc(sizeof(Bucket) + p->nKeyLength);
q->arKey = ((char*)q) + sizeof(Bucket);
memcpy((char*)q->arKey, p->arKey, p->nKeyLength);
q = ht->arData + ht->nNumUsed;
q->next = ht->arHash[nIndex].idx;
ht->arHash[nIndex].idx = ht->nNumUsed++;
}
#else
q = (Bucket *) emalloc(sizeof(Bucket) - 1 + p->nKeyLength);
if (p->nKeyLength) {
memcpy(q->arKey, p->arKey, p->nKeyLength);
}
#endif
/* Initialize key */
q->h = p->h;
q->nKeyLength = p->nKeyLength;
/* Insert into hash collision list */
q->pNext = ht->arBuckets[nIndex];
q->pLast = NULL;
if (q->pNext) {
q->pNext->pLast = q;
if (!p->nKeyLength) {
q->arKey = NULL;
} else if (IS_INTERNED(p->arKey)) {
q->arKey = p->arKey;
} else {
q->arKey = (const char *) emalloc(p->nKeyLength);
memcpy((char*)q->arKey, p->arKey, p->nKeyLength);
}
ht->arBuckets[nIndex] = q;
/* Insert into global list */
q->pListLast = ht->pListTail;
ht->pListTail = q;
q->pListNext = NULL;
*prev = q;
prev = &q->pListNext;
/* Copy data */
q->pData = (void *) emalloc(sizeof(zend_function));
new_entry = (zend_op_array*)q->pData;
*new_entry = *(zend_op_array*)p->pData;
q->pDataPtr = NULL;
q->xData = (void *) emalloc(sizeof(zend_function));
new_entry = (zend_op_array*)q->xData;
*new_entry = *(zend_op_array*)p->xData;
/* Copy constructor */
/* we use refcount to show that op_array is referenced from several places */
if (new_entry->refcount != NULL) {
accel_xlat_set(p->pData, new_entry);
accel_xlat_set(p->xData, new_entry);
}
zend_prepare_function_for_execution(new_entry);
@ -546,90 +538,78 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class
zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name, new_entry->function_name);
}
}
p = p->pListNext;
}
ht->pInternalPointer = ht->pListHead;
}
static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_class_entry *old_ce, zend_class_entry *ce TSRMLS_DC)
{
Bucket *p, *q, **prev;
uint idx;
Bucket *p, *q;
ulong nIndex;
zend_class_entry **new_ce;
zend_property_info *prop_info;
ht->nTableSize = source->nTableSize;
ht->nTableMask = source->nTableMask;
ht->nNumUsed = 0;
ht->nNumOfElements = source->nNumOfElements;
ht->nNextFreeElement = source->nNextFreeElement;
ht->pDestructor = (dtor_func_t) zend_destroy_property_info;
#if ZEND_DEBUG
ht->inconsistent = 0;
#endif
ht->persistent = 0;
ht->pListHead = NULL;
ht->pListTail = NULL;
ht->pInternalPointer = NULL;
ht->flags = HASH_FLAG_APPLY_PROTECTION | HASH_FLAG_BIG_DATA;
ht->nInternalPointer = source->nNumOfElements ? 0 : INVALID_IDX;
ht->nApplyCount = 0;
ht->bApplyProtection = 1;
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
if (!ht->nTableMask) {
ht->arBuckets = (Bucket**)&uninitialized_bucket;
ht->arHash = (HashBucket*)&uninitialized_bucket;
return;
}
#endif
ht->arBuckets = (Bucket **) ecalloc(ht->nTableSize, sizeof(Bucket *));
ht->arData = (Bucket *) ecalloc(ht->nTableSize, sizeof(Bucket));
if (source->flags & HASH_FLAG_PACKED) {
ht->flags |= HASH_FLAG_PACKED;
ht->arHash = (HashBucket*)&uninitialized_bucket;
} else {
ht->arHash = (HashBucket *) ecalloc(ht->nTableSize, sizeof(HashBucket));
memset(ht->arHash, INVALID_IDX, sizeof(HashBucket) * ht->nTableSize);
}
for (idx = 0; idx < source->nNumUsed; idx++) {
p = source->arData + idx;
if (!p->xData) continue;
prev = &ht->pListHead;
p = source->pListHead;
while (p) {
nIndex = p->h & ht->nTableMask;
/* Create bucket and initialize key */
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
if (!p->nKeyLength) {
q = (Bucket *) emalloc(sizeof(Bucket));
q->arKey = NULL;
} else if (IS_INTERNED(p->arKey)) {
q = (Bucket *) emalloc(sizeof(Bucket));
q->arKey = p->arKey;
/* Insert into hash collision list */
if (source->flags & HASH_FLAG_PACKED) {
q = ht->arData + p->h;
ht->nNumUsed = p->h + 1;
} else {
q = (Bucket *) emalloc(sizeof(Bucket) + p->nKeyLength);
q->arKey = ((char*)q) + sizeof(Bucket);
memcpy((char*)q->arKey, p->arKey, p->nKeyLength);
q = ht->arData + ht->nNumUsed;
q->next = ht->arHash[nIndex].idx;
ht->arHash[nIndex].idx = ht->nNumUsed++;
}
#else
q = (Bucket *) emalloc(sizeof(Bucket) - 1 + p->nKeyLength);
if (p->nKeyLength) {
memcpy(q->arKey, p->arKey, p->nKeyLength);
}
#endif
/* Initialize key */
q->h = p->h;
q->nKeyLength = p->nKeyLength;
/* Insert into hash collision list */
q->pNext = ht->arBuckets[nIndex];
q->pLast = NULL;
if (q->pNext) {
q->pNext->pLast = q;
if (!p->nKeyLength) {
q->arKey = NULL;
} else if (IS_INTERNED(p->arKey)) {
q->arKey = p->arKey;
} else {
q->arKey = (const char *) emalloc(p->nKeyLength);
memcpy((char*)q->arKey, p->arKey, p->nKeyLength);
}
ht->arBuckets[nIndex] = q;
/* Insert into global list */
q->pListLast = ht->pListTail;
ht->pListTail = q;
q->pListNext = NULL;
*prev = q;
prev = &q->pListNext;
/* Copy data */
q->pData = (void *) emalloc(sizeof(zend_property_info));
prop_info = q->pData;
*prop_info = *(zend_property_info*)p->pData;
q->pDataPtr = NULL;
q->xData = (void *) emalloc(sizeof(zend_property_info));
prop_info = q->xData;
*prop_info = *(zend_property_info*)p->xData;
/* Copy constructor */
prop_info->name = interned_estrndup(prop_info->name, prop_info->name_length);
@ -647,10 +627,7 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla
} else {
zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s, property %s", ce->name, prop_info->name);
}
p = p->pListNext;
}
ht->pInternalPointer = ht->pListHead;
}
/* protects reference count, creates copy of statics */
@ -879,13 +856,15 @@ static void zend_class_copy_ctor(zend_class_entry **pce)
static int zend_hash_unique_copy(HashTable *target, HashTable *source, unique_copy_ctor_func_t pCopyConstructor, uint size, int ignore_dups, void **fail_data, void **conflict_data)
{
uint idx;
Bucket *p;
void *t;
p = source->pListHead;
while (p) {
for (idx = 0; idx < source->nNumUsed; idx++) {
p = source->arData + idx;
if (!p->xData) continue;
if (p->nKeyLength > 0) {
if (zend_hash_quick_add(target, p->arKey, p->nKeyLength, p->h, p->pData, size, &t) == SUCCESS) {
if (zend_hash_quick_add(target, p->arKey, p->nKeyLength, p->h, HASH_DATA(source, p), size, &t) == SUCCESS) {
if (pCopyConstructor) {
pCopyConstructor(t);
}
@ -893,9 +872,9 @@ static int zend_hash_unique_copy(HashTable *target, HashTable *source, unique_co
if (p->nKeyLength > 0 && p->arKey[0] == 0) {
/* Mangled key */
#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
if (((zend_function*)p->pData)->common.fn_flags & ZEND_ACC_CLOSURE) {
if (((zend_function*)p->xData)->common.fn_flags & ZEND_ACC_CLOSURE) {
/* update closure */
if (zend_hash_quick_update(target, p->arKey, p->nKeyLength, p->h, p->pData, size, &t) == SUCCESS) {
if (zend_hash_quick_update(target, p->arKey, p->nKeyLength, p->h, HASH_DATA(source, p), size, &t) == SUCCESS) {
if (pCopyConstructor) {
pCopyConstructor(t);
}
@ -905,25 +884,24 @@ static int zend_hash_unique_copy(HashTable *target, HashTable *source, unique_co
}
#endif
} else if (!ignore_dups && zend_hash_quick_find(target, p->arKey, p->nKeyLength, p->h, &t) == SUCCESS) {
*fail_data = p->pData;
*fail_data = HASH_DATA(source, p);
*conflict_data = t;
return FAILURE;
}
}
} else {
if (!zend_hash_index_exists(target, p->h) && zend_hash_index_update(target, p->h, p->pData, size, &t) == SUCCESS) {
if (!zend_hash_index_exists(target, p->h) && zend_hash_index_update(target, p->h, HASH_DATA(source, p), size, &t) == SUCCESS) {
if (pCopyConstructor) {
pCopyConstructor(t);
}
} else if (!ignore_dups && zend_hash_index_find(target,p->h, &t) == SUCCESS) {
*fail_data = p->pData;
*fail_data = HASH_DATA(source, p);
*conflict_data = t;
return FAILURE;
}
}
p = p->pListNext;
}
target->pInternalPointer = target->pListHead;
target->nInternalPointer = target->nNumOfElements ? 0 : INVALID_IDX;
return SUCCESS;
}

View file

@ -54,89 +54,43 @@ static void zend_persist_zval_ptr(zval **zp TSRMLS_DC);
static void zend_persist_zval(zval *z TSRMLS_DC);
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
static const Bucket *uninitialized_bucket = NULL;
static const HashBucket uninitialized_bucket = {INVALID_IDX};
#endif
static void zend_hash_persist(HashTable *ht, void (*pPersistElement)(void *pElement TSRMLS_DC), size_t el_size TSRMLS_DC)
{
Bucket *p = ht->pListHead;
uint i;
uint idx;
Bucket *p;
while (p) {
Bucket *q = p;
if (!ht->nTableMask) {
ht->arHash = (HashBucket*)&uninitialized_bucket;
return;
}
zend_accel_store(ht->arData, sizeof(Bucket) * ht->nTableSize);
if (!(ht->flags & HASH_FLAG_PACKED)) {
zend_accel_store(ht->arHash, sizeof(HashBucket) * ht->nTableSize);
} else {
ht->arHash = (HashBucket*)&uninitialized_bucket;
}
for (idx = 0; idx < ht->nNumUsed; idx++) {
p = ht->arData + idx;
if (!p->xData) continue;
/* persist bucket and key */
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
p = zend_accel_memdup(p, sizeof(Bucket));
if (p->nKeyLength) {
p->arKey = zend_accel_memdup_interned_string(p->arKey, p->nKeyLength);
zend_accel_store_interned_string(p->arKey, p->nKeyLength);
}
#else
p = zend_accel_memdup(p, sizeof(Bucket) - 1 + p->nKeyLength);
#endif
/* persist data pointer in bucket */
if (!p->pDataPtr) {
zend_accel_store(p->pData, el_size);
} else {
/* Update p->pData to point to the new p->pDataPtr address, after the bucket relocation */
p->pData = &p->pDataPtr;
if (ht->flags & HASH_FLAG_BIG_DATA) {
zend_accel_store(p->xData, el_size);
}
/* persist the data itself */
if (pPersistElement) {
pPersistElement(p->pData TSRMLS_CC);
pPersistElement(HASH_DATA(ht, p) TSRMLS_CC);
}
/* update linked lists */
if (p->pLast) {
p->pLast->pNext = p;
}
if (p->pNext) {
p->pNext->pLast = p;
}
if (p->pListLast) {
p->pListLast->pListNext = p;
}
if (p->pListNext) {
p->pListNext->pListLast = p;
}
p = p->pListNext;
/* delete the old non-persistent bucket */
efree(q);
}
/* update linked lists */
if (ht->pListHead) {
ht->pListHead = zend_shared_alloc_get_xlat_entry(ht->pListHead);
}
if (ht->pListTail) {
ht->pListTail = zend_shared_alloc_get_xlat_entry(ht->pListTail);
}
if (ht->pInternalPointer) {
ht->pInternalPointer = zend_shared_alloc_get_xlat_entry(ht->pInternalPointer);
}
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
/* Check if HastTable is initialized */
if (ht->nTableMask) {
#endif
if (ht->nNumOfElements) {
/* update hash table */
for (i = 0; i < ht->nTableSize; i++) {
if (ht->arBuckets[i]) {
ht->arBuckets[i] = zend_shared_alloc_get_xlat_entry(ht->arBuckets[i]);
}
}
}
zend_accel_store(ht->arBuckets, sizeof(Bucket*) * ht->nTableSize);
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
} else {
ht->arBuckets = (Bucket**)&uninitialized_bucket;
}
#endif
}
#if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO

View file

@ -51,46 +51,44 @@ static uint zend_persist_zval_calc(zval *z TSRMLS_DC);
static uint zend_hash_persist_calc(HashTable *ht, int (*pPersistElement)(void *pElement TSRMLS_DC), size_t el_size TSRMLS_DC)
{
Bucket *p = ht->pListHead;
uint idx;
Bucket *p;
START_SIZE();
while (p) {
if (!ht->nTableMask) {
RETURN_SIZE();
}
ADD_DUP_SIZE(ht->arData, sizeof(Bucket) * ht->nTableSize);
if (!(ht->flags & HASH_FLAG_PACKED)) {
ADD_DUP_SIZE(ht->arHash, sizeof(HashBucket) * ht->nTableSize);
}
for (idx = 0; idx < ht->nNumUsed; idx++) {
p = ht->arData + idx;
if (!p->xData) continue;
/* persist bucket and key */
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
ADD_DUP_SIZE(p, sizeof(Bucket));
if (p->nKeyLength) {
const char *tmp = accel_new_interned_string(p->arKey, p->nKeyLength, 0 TSRMLS_CC);
if (tmp != p->arKey) {
efree(p->arKey);
p->arKey = tmp;
} else {
ADD_DUP_SIZE(p->arKey, p->nKeyLength);
}
}
#else
ADD_DUP_SIZE(p, sizeof(Bucket) - 1 + p->nKeyLength);
#endif
/* persist data pointer in bucket */
if (!p->pDataPtr) {
ADD_DUP_SIZE(p->pData, el_size);
if (ht->flags & HASH_FLAG_BIG_DATA) {
ADD_DUP_SIZE(p->xData, el_size);
}
/* persist the data itself */
if (pPersistElement) {
ADD_SIZE(pPersistElement(p->pData TSRMLS_CC));
ADD_SIZE(pPersistElement(HASH_DATA(ht, p) TSRMLS_CC));
}
p = p->pListNext;
}
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
if (ht->nTableMask) {
ADD_DUP_SIZE(ht->arBuckets, sizeof(Bucket*) * ht->nTableSize);
}
#else
ADD_DUP_SIZE(ht->arBuckets, sizeof(Bucket*) * ht->nTableSize);
#endif
RETURN_SIZE();
}

View file

@ -86,9 +86,9 @@ static void pcre_handle_exec_error(int pcre_code TSRMLS_DC) /* {{{ */
}
/* }}} */
static void php_free_pcre_cache(void *data) /* {{{ */
static void php_free_pcre_cache(zval *data) /* {{{ */
{
pcre_cache_entry *pce = (pcre_cache_entry *) data;
pcre_cache_entry *pce = (pcre_cache_entry *) Z_PTR_P(data);
if (!pce) return;
pefree(pce->re, 1);
if (pce->extra) pefree(pce->extra, 1);
@ -167,7 +167,7 @@ static PHP_MSHUTDOWN_FUNCTION(pcre)
/* }}} */
/* {{{ static pcre_clean_cache */
static int pcre_clean_cache(void *data, void *arg TSRMLS_DC)
static int pcre_clean_cache(zval *data, void *arg TSRMLS_DC)
{
int *num_clean = (int *)arg;
@ -226,7 +226,7 @@ static char **make_subpats_table(int num_subpats, pcre_cache_entry *pce TSRMLS_D
/* {{{ pcre_get_compiled_regex_cache
*/
PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_len TSRMLS_DC)
PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(zend_string *regex TSRMLS_DC)
{
pcre *re = NULL;
pcre_extra *extra;
@ -248,7 +248,6 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le
#endif
pcre_cache_entry *pce;
pcre_cache_entry new_entry;
char *tmp = NULL;
#if HAVE_SETLOCALE
# if defined(PHP_WIN32) && defined(ZTS)
@ -259,7 +258,8 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le
/* Try to lookup the cached regex entry, and if successful, just pass
back the compiled pattern, otherwise go on and compile it. */
if (zend_hash_find(&PCRE_G(pcre_cache), regex, regex_len+1, (void **)&pce) == SUCCESS) {
pce = zend_hash_find_ptr(&PCRE_G(pcre_cache), regex);
if (pce) {
/*
* We use a quick pcre_fullinfo() check to see whether cache is corrupted, and if it
* is, we flush it and compile the pattern from scratch.
@ -277,14 +277,14 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le
}
}
p = regex;
p = regex->val;
/* Parse through the leading whitespace, and display a warning if we
get to the end without encountering a delimiter. */
while (isspace((int)*(unsigned char *)p)) p++;
if (*p == 0) {
php_error_docref(NULL TSRMLS_CC, E_WARNING,
p < regex + regex_len ? "Null byte in regex" : "Empty regular expression");
p < regex->val + regex->len ? "Null byte in regex" : "Empty regular expression");
return NULL;
}
@ -331,7 +331,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le
}
if (*pp == 0) {
if (pp < regex + regex_len) {
if (pp < regex->val + regex->len) {
php_error_docref(NULL TSRMLS_CC,E_WARNING, "Null byte in regex");
} else if (start_delimiter == end_delimiter) {
php_error_docref(NULL TSRMLS_CC,E_WARNING, "No ending delimiter '%c' found", delimiter);
@ -349,7 +349,7 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le
/* Parse through the options, setting appropriate flags. Display
a warning if we encounter an unknown modifier. */
while (pp < regex + regex_len) {
while (pp < regex->val + regex->len) {
switch (*pp++) {
/* Perl compatible options */
case 'i': coptions |= PCRE_CASELESS; break;
@ -455,16 +455,12 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le
* as hash keys especually for this table.
* See bug #63180
*/
if (IS_INTERNED(regex)) {
regex = tmp = estrndup(regex, regex_len);
}
STR_ADDREF(regex);
zend_hash_update(&PCRE_G(pcre_cache), regex, regex_len+1, (void *)&new_entry,
sizeof(pcre_cache_entry), (void**)&pce);
pce = zend_hash_update_mem(&PCRE_G(pcre_cache), regex, (void *)&new_entry,
sizeof(pcre_cache_entry));
if (tmp) {
efree(tmp);
}
STR_RELEASE(regex);
return pce;
}
@ -472,9 +468,9 @@ PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_le
/* {{{ pcre_get_compiled_regex
*/
PHPAPI pcre* pcre_get_compiled_regex(char *regex, pcre_extra **extra, int *preg_options TSRMLS_DC)
PHPAPI pcre* pcre_get_compiled_regex(zend_string *regex, pcre_extra **extra, int *preg_options TSRMLS_DC)
{
pcre_cache_entry * pce = pcre_get_compiled_regex_cache(regex, strlen(regex) TSRMLS_CC);
pcre_cache_entry * pce = pcre_get_compiled_regex_cache(regex TSRMLS_CC);
if (extra) {
*extra = pce ? pce->extra : NULL;
@ -489,9 +485,9 @@ PHPAPI pcre* pcre_get_compiled_regex(char *regex, pcre_extra **extra, int *preg_
/* {{{ pcre_get_compiled_regex_ex
*/
PHPAPI pcre* pcre_get_compiled_regex_ex(char *regex, pcre_extra **extra, int *preg_options, int *compile_options TSRMLS_DC)
PHPAPI pcre* pcre_get_compiled_regex_ex(zend_string *regex, pcre_extra **extra, int *preg_options, int *compile_options TSRMLS_DC)
{
pcre_cache_entry * pce = pcre_get_compiled_regex_cache(regex, strlen(regex) TSRMLS_CC);
pcre_cache_entry * pce = pcre_get_compiled_regex_cache(regex TSRMLS_CC);
if (extra) {
*extra = pce ? pce->extra : NULL;
@ -510,43 +506,40 @@ PHPAPI pcre* pcre_get_compiled_regex_ex(char *regex, pcre_extra **extra, int *pr
/* {{{ add_offset_pair */
static inline void add_offset_pair(zval *result, char *str, int len, int offset, char *name)
{
zval *match_pair;
zval match_pair;
ALLOC_ZVAL(match_pair);
array_init(match_pair);
INIT_PZVAL(match_pair);
array_init(&match_pair);
/* Add (match, offset) to the return value */
add_next_index_stringl(match_pair, str, len, 1);
add_next_index_long(match_pair, offset);
add_next_index_stringl(&match_pair, str, len, 1);
add_next_index_long(&match_pair, offset);
if (name) {
zval_add_ref(&match_pair);
zend_hash_update(Z_ARRVAL_P(result), name, strlen(name)+1, &match_pair, sizeof(zval *), NULL);
zend_hash_str_update(Z_ARRVAL_P(result), name, strlen(name), &match_pair);
}
zend_hash_next_index_insert(Z_ARRVAL_P(result), &match_pair, sizeof(zval *), NULL);
zend_hash_next_index_insert(Z_ARRVAL_P(result), &match_pair);
}
/* }}} */
static void php_do_pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global) /* {{{ */
{
/* parameters */
char *regex; /* Regular expression */
zend_string *regex; /* Regular expression */
char *subject; /* String to match against */
int regex_len;
int subject_len;
pcre_cache_entry *pce; /* Compiled regular expression */
zval *subpats = NULL; /* Array for subpatterns */
long flags = 0; /* Match control flags */
long start_offset = 0; /* Where the new search starts */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|zll", &regex, &regex_len,
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ss|zll", &regex,
&subject, &subject_len, &subpats, &flags, &start_offset) == FAILURE) {
RETURN_FALSE;
}
/* Compile regex or get it from cache. */
if ((pce = pcre_get_compiled_regex_cache(regex, regex_len TSRMLS_CC)) == NULL) {
if ((pce = pcre_get_compiled_regex_cache(regex TSRMLS_CC)) == NULL) {
RETURN_FALSE;
}
@ -559,9 +552,9 @@ static void php_do_pcre_match(INTERNAL_FUNCTION_PARAMETERS, int global) /* {{{ *
PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subject_len, zval *return_value,
zval *subpats, int global, int use_flags, long flags, long start_offset TSRMLS_DC)
{
zval *result_set, /* Holds a set of subpatterns after
zval result_set, /* Holds a set of subpatterns after
a global match */
**match_sets = NULL; /* An array of sets of matches for each
*match_sets = NULL; /* An array of sets of matches for each
subpattern after a global match */
pcre_extra *extra = pce->extra;/* Holds results of studying */
pcre_extra extra_data; /* Used locally for exec options */
@ -643,11 +636,9 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec
/* Allocate match sets array and initialize the values. */
if (global && subpats && subpats_order == PREG_PATTERN_ORDER) {
match_sets = (zval **)safe_emalloc(num_subpats, sizeof(zval *), 0);
match_sets = (zval *)safe_emalloc(num_subpats, sizeof(zval), 0);
for (i=0; i<num_subpats; i++) {
ALLOC_ZVAL(match_sets[i]);
array_init(match_sets[i]);
INIT_PZVAL(match_sets[i]);
array_init(&match_sets[i]);
}
}
@ -688,10 +679,10 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec
/* For each subpattern, insert it into the appropriate array. */
for (i = 0; i < count; i++) {
if (offset_capture) {
add_offset_pair(match_sets[i], (char *)stringlist[i],
add_offset_pair(&match_sets[i], (char *)stringlist[i],
offsets[(i<<1)+1] - offsets[i<<1], offsets[i<<1], NULL);
} else {
add_next_index_stringl(match_sets[i], (char *)stringlist[i],
add_next_index_stringl(&match_sets[i], (char *)stringlist[i],
offsets[(i<<1)+1] - offsets[i<<1], 1);
}
}
@ -702,31 +693,29 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec
*/
if (count < num_subpats) {
for (; i < num_subpats; i++) {
add_next_index_string(match_sets[i], "", 1);
add_next_index_string(&match_sets[i], "", 1);
}
}
} else {
/* Allocate the result set array */
ALLOC_ZVAL(result_set);
array_init(result_set);
INIT_PZVAL(result_set);
array_init(&result_set);
/* Add all the subpatterns to it */
for (i = 0; i < count; i++) {
if (offset_capture) {
add_offset_pair(result_set, (char *)stringlist[i],
add_offset_pair(&result_set, (char *)stringlist[i],
offsets[(i<<1)+1] - offsets[i<<1], offsets[i<<1], subpat_names[i]);
} else {
if (subpat_names[i]) {
add_assoc_stringl(result_set, subpat_names[i], (char *)stringlist[i],
add_assoc_stringl(&result_set, subpat_names[i], (char *)stringlist[i],
offsets[(i<<1)+1] - offsets[i<<1], 1);
}
add_next_index_stringl(result_set, (char *)stringlist[i],
add_next_index_stringl(&result_set, (char *)stringlist[i],
offsets[(i<<1)+1] - offsets[i<<1], 1);
}
}
/* And add it to the output array */
zend_hash_next_index_insert(Z_ARRVAL_P(subpats), &result_set, sizeof(zval *), NULL);
zend_hash_next_index_insert(Z_ARRVAL_P(subpats), &result_set);
}
} else { /* single pattern matching */
/* For each subpattern, insert it into the subpatterns array. */
@ -777,11 +766,11 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, char *subject, int subjec
if (global && subpats && subpats_order == PREG_PATTERN_ORDER) {
for (i = 0; i < num_subpats; i++) {
if (subpat_names[i]) {
zend_hash_update(Z_ARRVAL_P(subpats), subpat_names[i],
strlen(subpat_names[i])+1, &match_sets[i], sizeof(zval *), NULL);
Z_ADDREF_P(match_sets[i]);
zend_hash_str_update(Z_ARRVAL_P(subpats), subpat_names[i],
strlen(subpat_names[i]), &match_sets[i]);
Z_ADDREF(match_sets[i]);
}
zend_hash_next_index_insert(Z_ARRVAL_P(subpats), &match_sets[i], sizeof(zval *), NULL);
zend_hash_next_index_insert(Z_ARRVAL_P(subpats), &match_sets[i]);
}
efree(match_sets);
}
@ -857,27 +846,24 @@ static int preg_get_backref(char **str, int *backref)
*/
static int preg_do_repl_func(zval *function, char *subject, int *offsets, char **subpat_names, int count, char **result TSRMLS_DC)
{
zval *retval_ptr; /* Function return value */
zval **args[1]; /* Argument to pass to function */
zval *subpats; /* Captured subpatterns */
zval retval; /* Function return value */
zval args[1]; /* Argument to pass to function */
int result_len; /* Return value length */
int i;
MAKE_STD_ZVAL(subpats);
array_init(subpats);
array_init(&args[0]);
for (i = 0; i < count; i++) {
if (subpat_names[i]) {
add_assoc_stringl(subpats, subpat_names[i], &subject[offsets[i<<1]] , offsets[(i<<1)+1] - offsets[i<<1], 1);
add_assoc_stringl(&args[0], subpat_names[i], &subject[offsets[i<<1]] , offsets[(i<<1)+1] - offsets[i<<1], 1);
}
add_next_index_stringl(subpats, &subject[offsets[i<<1]], offsets[(i<<1)+1] - offsets[i<<1], 1);
add_next_index_stringl(&args[0], &subject[offsets[i<<1]], offsets[(i<<1)+1] - offsets[i<<1], 1);
}
args[0] = &subpats;
if (call_user_function_ex(EG(function_table), NULL, function, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) == SUCCESS && retval_ptr) {
convert_to_string_ex(&retval_ptr);
*result = estrndup(Z_STRVAL_P(retval_ptr), Z_STRLEN_P(retval_ptr));
result_len = Z_STRLEN_P(retval_ptr);
zval_ptr_dtor(&retval_ptr);
if (call_user_function_ex(EG(function_table), NULL, function, &retval, 1, args, 0, NULL TSRMLS_CC) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
convert_to_string_ex(&retval);
*result = estrndup(Z_STRVAL(retval), Z_STRLEN(retval));
result_len = Z_STRLEN(retval);
zval_ptr_dtor(&retval);
} else {
if (!EG(exception)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call custom replacement function");
@ -886,7 +872,7 @@ static int preg_do_repl_func(zval *function, char *subject, int *offsets, char *
*result = estrndup(&subject[offsets[0]], result_len);
}
zval_ptr_dtor(&subpats);
zval_ptr_dtor(&args[0]);
return result_len;
}
@ -982,7 +968,7 @@ static int preg_do_eval(char *eval_str, int eval_str_len, char *subject,
/* {{{ php_pcre_replace
*/
PHPAPI char *php_pcre_replace(char *regex, int regex_len,
PHPAPI char *php_pcre_replace(zend_string *regex,
char *subject, int subject_len,
zval *replace_val, int is_callable_replace,
int *result_len, int limit, int *replace_count TSRMLS_DC)
@ -990,7 +976,7 @@ PHPAPI char *php_pcre_replace(char *regex, int regex_len,
pcre_cache_entry *pce; /* Compiled regular expression */
/* Compile regex or get it from cache. */
if ((pce = pcre_get_compiled_regex_cache(regex, regex_len TSRMLS_CC)) == NULL) {
if ((pce = pcre_get_compiled_regex_cache(regex TSRMLS_CC)) == NULL) {
return NULL;
}
@ -1161,7 +1147,7 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub
if (eval || is_callable_replace) {
memcpy(walkbuf, eval_result, eval_result_len);
*result_len += eval_result_len;
STR_FREE(eval_result);
if (eval_result) efree(eval_result);
} else { /* do regular backreference copying */
walk = replace;
walk_last = 0;
@ -1243,12 +1229,12 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub
/* {{{ php_replace_in_subject
*/
static char *php_replace_in_subject(zval *regex, zval *replace, zval **subject, int *result_len, int limit, int is_callable_replace, int *replace_count TSRMLS_DC)
static char *php_replace_in_subject(zval *regex, zval *replace, zval *subject, int *result_len, int limit, int is_callable_replace, int *replace_count TSRMLS_DC)
{
zval **regex_entry,
**replace_entry = NULL,
*replace_value,
empty_replace;
zval *regex_entry,
*replace_entry = NULL,
*replace_value,
empty_replace;
char *subject_value,
*result;
int subject_len;
@ -1256,13 +1242,14 @@ static char *php_replace_in_subject(zval *regex, zval *replace, zval **subject,
/* Make sure we're dealing with strings. */
convert_to_string_ex(subject);
/* FIXME: This might need to be changed to STR_EMPTY_ALLOC(). Check if this zval could be dtor()'ed somehow */
ZVAL_STRINGL(&empty_replace, "", 0, 0);
//??? ZVAL_STRINGL(&empty_replace, "", 0, 0);
ZVAL_EMPTY_STRING(&empty_replace);
/* If regex is an array */
if (Z_TYPE_P(regex) == IS_ARRAY) {
/* Duplicate subject string for repeated replacement */
subject_value = estrndup(Z_STRVAL_PP(subject), Z_STRLEN_PP(subject));
subject_len = Z_STRLEN_PP(subject);
subject_value = estrndup(Z_STRVAL_P(subject), Z_STRLEN_P(subject));
subject_len = Z_STRLEN_P(subject);
*result_len = subject_len;
zend_hash_internal_pointer_reset(Z_ARRVAL_P(regex));
@ -1272,18 +1259,18 @@ static char *php_replace_in_subject(zval *regex, zval *replace, zval **subject,
zend_hash_internal_pointer_reset(Z_ARRVAL_P(replace));
/* For each entry in the regex array, get the entry */
while (zend_hash_get_current_data(Z_ARRVAL_P(regex), (void **)&regex_entry) == SUCCESS) {
while ((regex_entry = zend_hash_get_current_data(Z_ARRVAL_P(regex))) != NULL) {
/* Make sure we're dealing with strings. */
convert_to_string_ex(regex_entry);
/* If replace is an array and not a callable construct */
if (Z_TYPE_P(replace) == IS_ARRAY && !is_callable_replace) {
/* Get current entry */
if (zend_hash_get_current_data(Z_ARRVAL_P(replace), (void **)&replace_entry) == SUCCESS) {
if ((replace_entry = zend_hash_get_current_data(Z_ARRVAL_P(replace))) != NULL) {
if (!is_callable_replace) {
convert_to_string_ex(replace_entry);
}
replace_value = *replace_entry;
replace_value = replace_entry;
zend_hash_move_forward(Z_ARRVAL_P(replace));
} else {
/* We've run out of replacement strings, so use an empty one */
@ -1293,8 +1280,7 @@ static char *php_replace_in_subject(zval *regex, zval *replace, zval **subject,
/* Do the actual replacement and put the result back into subject_value
for further replacements. */
if ((result = php_pcre_replace(Z_STRVAL_PP(regex_entry),
Z_STRLEN_PP(regex_entry),
if ((result = php_pcre_replace(Z_STR_P(regex_entry),
subject_value,
subject_len,
replace_value,
@ -1315,10 +1301,9 @@ static char *php_replace_in_subject(zval *regex, zval *replace, zval **subject,
return subject_value;
} else {
result = php_pcre_replace(Z_STRVAL_P(regex),
Z_STRLEN_P(regex),
Z_STRVAL_PP(subject),
Z_STRLEN_PP(subject),
result = php_pcre_replace(Z_STR_P(regex),
Z_STRVAL_P(subject),
Z_STRLEN_P(subject),
replace,
is_callable_replace,
result_len,
@ -1333,40 +1318,39 @@ static char *php_replace_in_subject(zval *regex, zval *replace, zval **subject,
*/
static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_replace, int is_filter)
{
zval **regex,
**replace,
**subject,
**subject_entry,
**zcount = NULL;
zval *regex,
*replace,
*subject,
*subject_entry,
*zcount = NULL;
char *result;
int result_len;
int limit_val = -1;
long limit = -1;
char *string_key;
uint string_key_len;
zend_string *string_key;
ulong num_key;
char *callback_name;
int replace_count=0, old_replace_count;
/* Get function parameters and do error-checking. */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZZ|lZ", &regex, &replace, &subject, &limit, &zcount) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz|lz", &regex, &replace, &subject, &limit, &zcount) == FAILURE) {
return;
}
if (!is_callable_replace && Z_TYPE_PP(replace) == IS_ARRAY && Z_TYPE_PP(regex) != IS_ARRAY) {
if (!is_callable_replace && Z_TYPE_P(replace) == IS_ARRAY && Z_TYPE_P(regex) != IS_ARRAY) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Parameter mismatch, pattern is a string while replacement is an array");
RETURN_FALSE;
}
SEPARATE_ZVAL(replace);
if (Z_TYPE_PP(replace) != IS_ARRAY && (Z_TYPE_PP(replace) != IS_OBJECT || !is_callable_replace)) {
if (Z_TYPE_P(replace) != IS_ARRAY && (Z_TYPE_P(replace) != IS_OBJECT || !is_callable_replace)) {
convert_to_string_ex(replace);
}
if (is_callable_replace) {
if (!zend_is_callable(*replace, 0, &callback_name TSRMLS_CC)) {
if (!zend_is_callable(replace, 0, &callback_name TSRMLS_CC)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Requires argument 2, '%s', to be a valid callback", callback_name);
efree(callback_name);
MAKE_COPY_ZVAL(subject, return_value);
ZVAL_DUP(return_value, subject);
return;
}
efree(callback_name);
@ -1379,26 +1363,27 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl
limit_val = limit;
}
if (Z_TYPE_PP(regex) != IS_ARRAY)
if (Z_TYPE_P(regex) != IS_ARRAY)
convert_to_string_ex(regex);
/* if subject is an array */
if (Z_TYPE_PP(subject) == IS_ARRAY) {
if (Z_TYPE_P(subject) == IS_ARRAY) {
array_init(return_value);
zend_hash_internal_pointer_reset(Z_ARRVAL_PP(subject));
zend_hash_internal_pointer_reset(Z_ARRVAL_P(subject));
/* For each subject entry, convert it to string, then perform replacement
and add the result to the return_value array. */
while (zend_hash_get_current_data(Z_ARRVAL_PP(subject), (void **)&subject_entry) == SUCCESS) {
while ((subject_entry = zend_hash_get_current_data(Z_ARRVAL_P(subject))) != NULL) {
SEPARATE_ZVAL(subject_entry);
old_replace_count = replace_count;
if ((result = php_replace_in_subject(*regex, *replace, subject_entry, &result_len, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) {
if ((result = php_replace_in_subject(regex, replace, subject_entry, &result_len, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) {
if (!is_filter || replace_count > old_replace_count) {
/* Add to return array */
switch(zend_hash_get_current_key_ex(Z_ARRVAL_PP(subject), &string_key, &string_key_len, &num_key, 0, NULL))
switch(zend_hash_get_current_key_ex(Z_ARRVAL_P(subject), &string_key, &num_key, 0, NULL))
{
case HASH_KEY_IS_STRING:
add_assoc_stringl_ex(return_value, string_key, string_key_len, result, result_len, 0);
//???
add_assoc_stringl_ex(return_value, string_key->val, string_key->len, result, result_len, 0);
break;
case HASH_KEY_IS_LONG:
@ -1410,21 +1395,22 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl
}
}
zend_hash_move_forward(Z_ARRVAL_PP(subject));
zend_hash_move_forward(Z_ARRVAL_P(subject));
}
} else { /* if subject is not an array */
old_replace_count = replace_count;
if ((result = php_replace_in_subject(*regex, *replace, subject, &result_len, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) {
if ((result = php_replace_in_subject(regex, replace, subject, &result_len, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) {
if (!is_filter || replace_count > old_replace_count) {
RETVAL_STRINGL(result, result_len, 0);
//??? RETVAL_STRINGL(result, result_len, 0);
RETVAL_STRINGL(result, result_len);
} else {
efree(result);
}
}
}
if (ZEND_NUM_ARGS() > 4) {
zval_dtor(*zcount);
ZVAL_LONG(*zcount, replace_count);
zval_dtor(zcount);
ZVAL_LONG(zcount, replace_count);
}
}
@ -1458,22 +1444,21 @@ static PHP_FUNCTION(preg_filter)
Split string into an array using a perl-style regular expression as a delimiter */
static PHP_FUNCTION(preg_split)
{
char *regex; /* Regular expression */
zend_string *regex; /* Regular expression */
char *subject; /* String to match against */
int regex_len;
int subject_len;
long limit_val = -1;/* Integer value of limit */
long flags = 0; /* Match control flags */
pcre_cache_entry *pce; /* Compiled regular expression */
/* Get function parameters and do error checking */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|ll", &regex, &regex_len,
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ss|ll", &regex,
&subject, &subject_len, &limit_val, &flags) == FAILURE) {
RETURN_FALSE;
}
/* Compile regex or get it from cache. */
if ((pce = pcre_get_compiled_regex_cache(regex, regex_len TSRMLS_CC)) == NULL) {
if ((pce = pcre_get_compiled_regex_cache(regex TSRMLS_CC)) == NULL) {
RETURN_FALSE;
}
@ -1597,8 +1582,10 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, char *subject, int subjec
if (pce->compile_options & PCRE_UTF8) {
if (re_bump == NULL) {
int dummy;
if ((re_bump = pcre_get_compiled_regex("/./us", &extra_bump, &dummy TSRMLS_CC)) == NULL) {
zend_string *regex = STR_INIT("/./us", sizeof("/./us")-1, 0);
re_bump = pcre_get_compiled_regex(regex, &extra_bump, &dummy TSRMLS_CC);
STR_RELEASE(regex);
if (re_bump == NULL) {
RETURN_FALSE;
}
}
@ -1733,7 +1720,8 @@ static PHP_FUNCTION(preg_quote)
*q = '\0';
/* Reallocate string and return it */
RETVAL_STRINGL(erealloc(out_str, q - out_str + 1), q - out_str, 0);
//??? RETVAL_STRINGL(erealloc(out_str, q - out_str + 1), q - out_str, 0);
RETVAL_STRINGL(erealloc(out_str, q - out_str + 1), q - out_str);
}
/* }}} */
@ -1741,20 +1729,19 @@ static PHP_FUNCTION(preg_quote)
Searches array and returns entries which match regex */
static PHP_FUNCTION(preg_grep)
{
char *regex; /* Regular expression */
int regex_len;
zend_string *regex; /* Regular expression */
zval *input; /* Input array */
long flags = 0; /* Match control flags */
pcre_cache_entry *pce; /* Compiled regular expression */
/* Get arguments and do error checking */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|l", &regex, &regex_len,
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Sa|l", &regex,
&input, &flags) == FAILURE) {
return;
}
/* Compile regex or get it from cache. */
if ((pce = pcre_get_compiled_regex_cache(regex, regex_len TSRMLS_CC)) == NULL) {
if ((pce = pcre_get_compiled_regex_cache(regex TSRMLS_CC)) == NULL) {
RETURN_FALSE;
}
@ -1764,14 +1751,13 @@ static PHP_FUNCTION(preg_grep)
PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return_value, long flags TSRMLS_DC) /* {{{ */
{
zval **entry; /* An entry in the input array */
zval *entry; /* An entry in the input array */
pcre_extra *extra = pce->extra;/* Holds results of studying */
pcre_extra extra_data; /* Used locally for exec options */
int *offsets; /* Array of subpattern offsets */
int size_offsets; /* Size of the offsets array */
int count = 0; /* Count of matched subpatterns */
char *string_key;
uint string_key_len;
zend_string *string_key;
ulong num_key;
zend_bool invert; /* Whether to return non-matching
entries */
@ -1802,10 +1788,12 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return
/* Go through the input array */
zend_hash_internal_pointer_reset(Z_ARRVAL_P(input));
while (zend_hash_get_current_data(Z_ARRVAL_P(input), (void **)&entry) == SUCCESS) {
zval subject = **entry;
while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(input))) != NULL) {
zval subject;
ZVAL_COPY_VALUE(&subject, entry);
if (Z_TYPE_PP(entry) != IS_STRING) {
if (Z_TYPE_P(entry) != IS_STRING) {
zval_copy_ctor(&subject);
convert_to_string(&subject);
}
@ -1827,24 +1815,22 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return
/* If the entry fits our requirements */
if ((count > 0 && !invert) || (count == PCRE_ERROR_NOMATCH && invert)) {
Z_ADDREF_PP(entry);
Z_ADDREF_P(entry);
/* Add to return array */
switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &string_key_len, &num_key, 0, NULL))
switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &num_key, 0, NULL))
{
case HASH_KEY_IS_STRING:
zend_hash_update(Z_ARRVAL_P(return_value), string_key,
string_key_len, entry, sizeof(zval *), NULL);
zend_hash_update(Z_ARRVAL_P(return_value), string_key, entry);
break;
case HASH_KEY_IS_LONG:
zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry,
sizeof(zval *), NULL);
zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry);
break;
}
}
if (Z_TYPE_PP(entry) != IS_STRING) {
if (Z_TYPE_P(entry) != IS_STRING) {
zval_dtor(&subject);
}

View file

@ -33,9 +33,9 @@
#include <locale.h>
#endif
PHPAPI char *php_pcre_replace(char *regex, int regex_len, char *subject, int subject_len, zval *replace_val, int is_callable_replace, int *result_len, int limit, int *replace_count TSRMLS_DC);
PHPAPI pcre* pcre_get_compiled_regex(char *regex, pcre_extra **extra, int *options TSRMLS_DC);
PHPAPI pcre* pcre_get_compiled_regex_ex(char *regex, pcre_extra **extra, int *preg_options, int *coptions TSRMLS_DC);
PHPAPI char *php_pcre_replace(zend_string *regex, char *subject, int subject_len, zval *replace_val, int is_callable_replace, int *result_len, int limit, int *replace_count TSRMLS_DC);
PHPAPI pcre* pcre_get_compiled_regex(zend_string *regex, pcre_extra **extra, int *options TSRMLS_DC);
PHPAPI pcre* pcre_get_compiled_regex_ex(zend_string *regex, pcre_extra **extra, int *preg_options, int *coptions TSRMLS_DC);
extern zend_module_entry pcre_module_entry;
#define pcre_module_ptr &pcre_module_entry
@ -52,7 +52,7 @@ typedef struct {
int refcount;
} pcre_cache_entry;
PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(char *regex, int regex_len TSRMLS_DC);
PHPAPI pcre_cache_entry* pcre_get_compiled_regex_cache(zend_string *regex TSRMLS_DC);
PHPAPI void php_pcre_match_impl( pcre_cache_entry *pce, char *subject, int subject_len, zval *return_value,
zval *subpats, int global, int use_flags, long flags, long start_offset TSRMLS_DC);

View file

@ -372,7 +372,7 @@ PHP_MINIT_FUNCTION(pdo)
INIT_CLASS_ENTRY(ce, "PDOException", NULL);
pdo_exception_ce = zend_register_internal_class_ex(&ce, php_pdo_get_exception_base(0 TSRMLS_CC), NULL TSRMLS_CC);
pdo_exception_ce = zend_register_internal_class_ex(&ce, php_pdo_get_exception_base(0 TSRMLS_CC) TSRMLS_CC);
zend_declare_property_null(pdo_exception_ce, "errorInfo", sizeof("errorInfo")-1, ZEND_ACC_PUBLIC TSRMLS_CC);

View file

@ -470,14 +470,15 @@ static void pdo_stmt_construct(pdo_stmt_t *stmt, zval *object, zend_class_entry
fci.retval_ptr_ptr = &retval;
if (ctor_args) {
HashTable *ht = Z_ARRVAL_P(ctor_args);
uint idx;
Bucket *p;
fci.param_count = 0;
fci.params = safe_emalloc(sizeof(zval*), ht->nNumOfElements, 0);
p = ht->pListHead;
while (p != NULL) {
fci.params[fci.param_count++] = (zval**)p->pData;
p = p->pListNext;
for (idx = 0; idx < ht->nNumUsed; idx++) {
p = ht->arData + idx;
if (!p->xData) continue;
fci.params[fci.param_count++] = (zval**)&p->xData;
}
} else {
fci.param_count = 0;

View file

@ -759,14 +759,15 @@ static int do_fetch_class_prepare(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
fci->retval_ptr_ptr = &stmt->fetch.cls.retval_ptr;
if (stmt->fetch.cls.ctor_args) {
HashTable *ht = Z_ARRVAL_P(stmt->fetch.cls.ctor_args);
uint idx;
Bucket *p;
fci->param_count = 0;
fci->params = safe_emalloc(sizeof(zval**), ht->nNumOfElements, 0);
p = ht->pListHead;
while (p != NULL) {
fci->params[fci->param_count++] = (zval**)p->pData;
p = p->pListNext;
for (idx = 0; idx < ht->nNumUsed; idx++) {
p = ht->arData + idx;
if (!p->xData) continue;
fci->params[fci->param_count++] = (zval**)&p->xData;
}
} else {
fci->param_count = 0;

View file

@ -44,9 +44,9 @@ static int phar_dir_close(php_stream *stream, int close_handle TSRMLS_DC) /* {{
{
HashTable *data = (HashTable *)stream->abstract;
if (data && data->arBuckets) {
if (data && data->arHash) {
zend_hash_destroy(data);
data->arBuckets = 0;
data->arHash = 0;
FREE_HASHTABLE(data);
stream->abstract = NULL;
}
@ -158,8 +158,8 @@ static int phar_compare_dir_name(const void *a, const void *b TSRMLS_DC) /* {{{
Bucket *s;
int result;
f = *((Bucket **) a);
s = *((Bucket **) b);
f = (Bucket *) a;
s = (Bucket *) b;
result = zend_binary_strcmp(f->arKey, f->nKeyLength, s->arKey, s->nKeyLength);
if (result < 0) {
@ -359,7 +359,7 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, const char *path,
return ret;
}
if (!phar->manifest.arBuckets) {
if (!phar->manifest.arHash) {
php_url_free(resource);
return NULL;
}

View file

@ -33,8 +33,8 @@ PHAR_FUNC(phar_opendir) /* {{{ */
goto skip_phar;
}
if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
&& !cached_phars.arBuckets) {
if ((PHAR_GLOBALS->phar_fname_map.arHash && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
&& !cached_phars.arHash) {
goto skip_phar;
}
@ -107,8 +107,8 @@ PHAR_FUNC(phar_file_get_contents) /* {{{ */
goto skip_phar;
}
if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
&& !cached_phars.arBuckets) {
if ((PHAR_GLOBALS->phar_fname_map.arHash && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
&& !cached_phars.arHash) {
goto skip_phar;
}
@ -240,8 +240,8 @@ PHAR_FUNC(phar_readfile) /* {{{ */
goto skip_phar;
}
if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
&& !cached_phars.arBuckets) {
if ((PHAR_GLOBALS->phar_fname_map.arHash && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
&& !cached_phars.arHash) {
goto skip_phar;
}
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "p|br!", &filename, &filename_len, &use_include_path, &zcontext) == FAILURE) {
@ -335,8 +335,8 @@ PHAR_FUNC(phar_fopen) /* {{{ */
goto skip_phar;
}
if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
&& !cached_phars.arBuckets) {
if ((PHAR_GLOBALS->phar_fname_map.arHash && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
&& !cached_phars.arHash) {
/* no need to check, include_path not even specified in fopen/ no active phars */
goto skip_phar;
}
@ -901,8 +901,8 @@ PHAR_FUNC(phar_is_file) /* {{{ */
goto skip_phar;
}
if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
&& !cached_phars.arBuckets) {
if ((PHAR_GLOBALS->phar_fname_map.arHash && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
&& !cached_phars.arHash) {
goto skip_phar;
}
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) {
@ -968,8 +968,8 @@ PHAR_FUNC(phar_is_link) /* {{{ */
goto skip_phar;
}
if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
&& !cached_phars.arBuckets) {
if ((PHAR_GLOBALS->phar_fname_map.arHash && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
&& !cached_phars.arHash) {
goto skip_phar;
}
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "p", &filename, &filename_len) == FAILURE) {

View file

@ -82,7 +82,7 @@ ZEND_INI_MH(phar_ini_modify_handler) /* {{{ */
if (entry->name_length == 14) {
PHAR_G(readonly) = ini;
if (PHAR_GLOBALS->request_init && PHAR_GLOBALS->phar_fname_map.arBuckets) {
if (PHAR_GLOBALS->request_init && PHAR_GLOBALS->phar_fname_map.arHash) {
zend_hash_apply_with_argument(&(PHAR_GLOBALS->phar_fname_map), phar_set_writeable_bit, (void *)&ini TSRMLS_CC);
}
} else {
@ -147,9 +147,9 @@ finish_error:
PHAR_GLOBALS->manifest_cached = 0;
efree(tmp);
zend_hash_destroy(&(PHAR_G(phar_fname_map)));
PHAR_GLOBALS->phar_fname_map.arBuckets = 0;
PHAR_GLOBALS->phar_fname_map.arHash = 0;
zend_hash_destroy(&(PHAR_G(phar_alias_map)));
PHAR_GLOBALS->phar_alias_map.arBuckets = 0;
PHAR_GLOBALS->phar_alias_map.arHash = 0;
zend_hash_destroy(&cached_phars);
zend_hash_destroy(&cached_alias);
zend_hash_graceful_reverse_destroy(&EG(regular_list));
@ -174,8 +174,8 @@ finish_error:
zend_hash_destroy(&cached_alias);
cached_phars = PHAR_GLOBALS->phar_fname_map;
cached_alias = PHAR_GLOBALS->phar_alias_map;
PHAR_GLOBALS->phar_fname_map.arBuckets = 0;
PHAR_GLOBALS->phar_alias_map.arBuckets = 0;
PHAR_GLOBALS->phar_fname_map.arHash = 0;
PHAR_GLOBALS->phar_alias_map.arHash = 0;
zend_hash_graceful_reverse_destroy(&EG(regular_list));
memset(&EG(regular_list), 0, sizeof(HashTable));
efree(tmp);
@ -221,19 +221,19 @@ void phar_destroy_phar_data(phar_archive_data *phar TSRMLS_DC) /* {{{ */
phar->signature = NULL;
}
if (phar->manifest.arBuckets) {
if (phar->manifest.arHash) {
zend_hash_destroy(&phar->manifest);
phar->manifest.arBuckets = NULL;
phar->manifest.arHash = NULL;
}
if (phar->mounted_dirs.arBuckets) {
if (phar->mounted_dirs.arHash) {
zend_hash_destroy(&phar->mounted_dirs);
phar->mounted_dirs.arBuckets = NULL;
phar->mounted_dirs.arHash = NULL;
}
if (phar->virtual_dirs.arBuckets) {
if (phar->virtual_dirs.arHash) {
zend_hash_destroy(&phar->virtual_dirs);
phar->virtual_dirs.arBuckets = NULL;
phar->virtual_dirs.arHash = NULL;
}
if (phar->metadata) {
@ -3527,11 +3527,11 @@ PHP_RSHUTDOWN_FUNCTION(phar) /* {{{ */
{
phar_release_functions(TSRMLS_C);
zend_hash_destroy(&(PHAR_GLOBALS->phar_alias_map));
PHAR_GLOBALS->phar_alias_map.arBuckets = NULL;
PHAR_GLOBALS->phar_alias_map.arHash = NULL;
zend_hash_destroy(&(PHAR_GLOBALS->phar_fname_map));
PHAR_GLOBALS->phar_fname_map.arBuckets = NULL;
PHAR_GLOBALS->phar_fname_map.arHash = NULL;
zend_hash_destroy(&(PHAR_GLOBALS->phar_persist_map));
PHAR_GLOBALS->phar_persist_map.arBuckets = NULL;
PHAR_GLOBALS->phar_persist_map.arHash = NULL;
PHAR_GLOBALS->phar_SERVER_mung_list = 0;
if (PHAR_GLOBALS->cached_fp) {

View file

@ -536,7 +536,7 @@ carry_on:
}
return;
} else if (PHAR_GLOBALS->phar_fname_map.arBuckets && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void **)&pphar)) {
} else if (PHAR_GLOBALS->phar_fname_map.arHash && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), fname, fname_len, (void **)&pphar)) {
goto carry_on;
} else if (PHAR_G(manifest_cached) && SUCCESS == zend_hash_find(&cached_phars, fname, fname_len, (void **)&pphar)) {
if (SUCCESS == phar_copy_on_write(pphar TSRMLS_CC)) {
@ -5349,21 +5349,21 @@ void phar_object_init(TSRMLS_D) /* {{{ */
zend_class_entry ce;
INIT_CLASS_ENTRY(ce, "PharException", phar_exception_methods);
phar_ce_PharException = zend_register_internal_class_ex(&ce, phar_exception_get_default(), NULL TSRMLS_CC);
phar_ce_PharException = zend_register_internal_class_ex(&ce, phar_exception_get_default() TSRMLS_CC);
#if HAVE_SPL
INIT_CLASS_ENTRY(ce, "Phar", php_archive_methods);
phar_ce_archive = zend_register_internal_class_ex(&ce, spl_ce_RecursiveDirectoryIterator, NULL TSRMLS_CC);
phar_ce_archive = zend_register_internal_class_ex(&ce, spl_ce_RecursiveDirectoryIterator TSRMLS_CC);
zend_class_implements(phar_ce_archive TSRMLS_CC, 2, spl_ce_Countable, zend_ce_arrayaccess);
INIT_CLASS_ENTRY(ce, "PharData", php_archive_methods);
phar_ce_data = zend_register_internal_class_ex(&ce, spl_ce_RecursiveDirectoryIterator, NULL TSRMLS_CC);
phar_ce_data = zend_register_internal_class_ex(&ce, spl_ce_RecursiveDirectoryIterator TSRMLS_CC);
zend_class_implements(phar_ce_data TSRMLS_CC, 2, spl_ce_Countable, zend_ce_arrayaccess);
INIT_CLASS_ENTRY(ce, "PharFileInfo", php_entry_methods);
phar_ce_entry = zend_register_internal_class_ex(&ce, spl_ce_SplFileInfo, NULL TSRMLS_CC);
phar_ce_entry = zend_register_internal_class_ex(&ce, spl_ce_SplFileInfo TSRMLS_CC);
#else
INIT_CLASS_ENTRY(ce, "Phar", php_archive_methods);
phar_ce_archive = zend_register_internal_class(&ce TSRMLS_CC);

View file

@ -103,7 +103,7 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, const char *filename, const
if (mode[0] == 'w' || (mode[0] == 'r' && mode[1] == '+')) {
phar_archive_data **pphar = NULL, *phar;
if (PHAR_GLOBALS->request_init && PHAR_GLOBALS->phar_fname_map.arBuckets && FAILURE == zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **)&pphar)) {
if (PHAR_GLOBALS->request_init && PHAR_GLOBALS->phar_fname_map.arHash && FAILURE == zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **)&pphar)) {
pphar = NULL;
}
if (PHAR_G(readonly) && (!pphar || !(*pphar)->is_data)) {
@ -609,7 +609,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int f
php_url_free(resource);
return SUCCESS;
}
if (!phar->manifest.arBuckets) {
if (!phar->manifest.arHash) {
php_url_free(resource);
return FAILURE;
}
@ -626,7 +626,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, const char *url, int f
return SUCCESS;
}
/* check for mounted directories */
if (phar->mounted_dirs.arBuckets && zend_hash_num_elements(&phar->mounted_dirs)) {
if (phar->mounted_dirs.arHash && zend_hash_num_elements(&phar->mounted_dirs)) {
char *str_key;
ulong unused;
uint keylen;

Some files were not shown because too many files have changed in this diff Show more