more logic has been implemented.
%% /* Rules */
statement_list:
- statement_list { do_extended_info(CLS_C); } statement { HANDLE_INTERACTIVE(); }
+ statement_list { do_extended_info(CLS_C); } statement { ELS_FETCH(); HANDLE_INTERACTIVE(); }
| /* empty */
;
| REQUIRE CONSTANT_ENCAPSED_STRING ';' { require_filename($2.u.constant.value.str.val CLS_CC); zval_dtor(&$2.u.constant); }
| REQUIRE '(' CONSTANT_ENCAPSED_STRING ')' ';' { require_filename($3.u.constant.value.str.val CLS_CC); zval_dtor(&$3.u.constant); }
| ZEND_UNSET '(' r_cvar ')' ';' { do_unset(&$3 CLS_CC); }
- | ZEND_FOREACH '(' expr ZEND_AS { do_foreach_begin(&$1, &$3, &$2, &$4); } w_cvar foreach_optional_arg ')' { do_foreach_cont(&$6, &$7, &$4 CLS_CC); } foreach_statement { do_foreach_end(&$1, &$2 CLS_CC); }
+ | ZEND_FOREACH '(' expr ZEND_AS { do_foreach_begin(&$1, &$3, &$2, &$4 CLS_CC); } w_cvar foreach_optional_arg ')' { do_foreach_cont(&$6, &$7, &$4 CLS_CC); } foreach_statement { do_foreach_end(&$1, &$2 CLS_CC); }
| ';' /* empty statement */
;
reference_variable:
dim_list ']' { $$ = $1; }
- | compound_variable { do_fetch_globals(&$1); do_begin_variable_parse(CLS_C); fetch_simple_variable(&$$, &$1, 1 CLS_CC); }
+ | compound_variable { do_fetch_globals(&$1 CLS_CC); do_begin_variable_parse(CLS_C); fetch_simple_variable(&$$, &$1, 1 CLS_CC); }
;
dim_list:
dim_list ']' '[' dim_offset { fetch_array_dim(&$$, &$1, &$4 CLS_CC); }
- | compound_variable { do_fetch_globals(&$1); do_begin_variable_parse(CLS_C); } '[' dim_offset { fetch_array_begin(&$$, &$1, &$4 CLS_CC); }
+ | compound_variable { do_fetch_globals(&$1 CLS_CC); do_begin_variable_parse(CLS_C); } '[' dim_offset { fetch_array_begin(&$$, &$1, &$4 CLS_CC); }
;
| encaps_list '{' { $2.u.constant.value.chval = '{'; do_add_char(&$$, &$1, &$2 CLS_CC); }
| encaps_list '}' { $2.u.constant.value.chval = '}'; do_add_char(&$$, &$1, &$2 CLS_CC); }
| encaps_list ZEND_OBJECT_OPERATOR { znode tmp; $2.u.constant.value.chval = '-'; do_add_char(&tmp, &$1, &$2 CLS_CC); $2.u.constant.value.chval = '>'; do_add_char(&$$, &tmp, &$2 CLS_CC); }
- | /* empty */ { do_init_string(&$$); }
+ | /* empty */ { do_init_string(&$$ CLS_CC); }
;
encaps_var:
- VARIABLE { do_fetch_globals(&$1); do_begin_variable_parse(CLS_C); fetch_simple_variable(&$$, &$1, 1 CLS_CC); }
- | VARIABLE '[' { do_begin_variable_parse(CLS_C); } encaps_var_offset ']' { do_fetch_globals(&$1); fetch_array_begin(&$$, &$1, &$4 CLS_CC); }
+ VARIABLE { do_fetch_globals(&$1 CLS_CC); do_begin_variable_parse(CLS_C); fetch_simple_variable(&$$, &$1, 1 CLS_CC); }
+ | VARIABLE '[' { do_begin_variable_parse(CLS_C); } encaps_var_offset ']' { do_fetch_globals(&$1 CLS_CC); fetch_array_begin(&$$, &$1, &$4 CLS_CC); }
| VARIABLE ZEND_OBJECT_OPERATOR STRING { do_begin_variable_parse(CLS_C); fetch_simple_variable(&$2, &$1, 1 CLS_CC); do_fetch_property(&$$, &$2, &$3 CLS_CC); }
| DOLLAR_OPEN_CURLY_BRACES expr '}' { do_begin_variable_parse(CLS_C); fetch_simple_variable(&$$, &$2, 1 CLS_CC); }
| DOLLAR_OPEN_CURLY_BRACES STRING '[' expr ']' '}' { do_begin_variable_parse(CLS_C); fetch_array_begin(&$$, &$2, &$4 CLS_CC); }
-ZEND_API zend_op_array *compile_files(int mark_as_ref ELS_DC, int file_count, ...)
+ZEND_API zend_op_array *compile_files(int mark_as_ref CLS_DC, int file_count, ...)
{
va_list files;
zend_op_array *op_array;
va_start(files, file_count);
- op_array = v_compile_files(mark_as_ref ELS_CC, file_count, files);
+ op_array = v_compile_files(mark_as_ref CLS_CC, file_count, files);
va_end(files);
return op_array;
}
-ZEND_API zend_op_array *v_compile_files(int mark_as_ref ELS_DC, int file_count, va_list files)
+ZEND_API zend_op_array *v_compile_files(int mark_as_ref CLS_DC, int file_count, va_list files)
{
zend_lex_state original_lex_state;
zend_op_array *op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
#include "zend_constants.h"
#include "zend_list.h"
+#ifdef ZTS
+# define GLOBAL_FUNCTION_TABLE global_function_table
+# define GLOBAL_CLASS_TABLE global_class_table
+#else
+# define GLOBAL_FUNCTION_TABLE CG(function_table)
+# define GLOBAL_CLASS_TABLE CG(class_table)
+#endif
+
/* true multithread-shared globals */
zend_class_entry standard_class;
ZEND_API int (*zend_printf)(const char *format, ...);
FILE *(*zend_fopen)(const char *filename);
void (*zend_block_interruptions)();
void (*zend_unblock_interruptions)();
+#ifdef ZTS
+int compiler_globals_id;
+int executor_globals_id;
+int alloc_globals_id;
+HashTable *global_function_table;
+HashTable *global_class_table;
+#endif
zend_utility_values zend_uv;
ZEND_PUTS(")\n");
}
+
ZEND_API int zend_print_zval(zval *expr, int indent)
{
zval expr_copy;
static void register_standard_class()
{
+ CLS_FETCH();
+
standard_class.type = ZEND_INTERNAL_CLASS;
standard_class.name_length = sizeof("stdClass") - 1;
standard_class.name = zend_strndup("stdClass", standard_class.name_length);
standard_class.handle_property_set = NULL;
standard_class.refcount = (int *) malloc(sizeof(int));
*standard_class.refcount = 1;
- zend_hash_add(CG(class_table), "stdClass", sizeof("stdClass"), &standard_class, sizeof(zend_class_entry), NULL);
+ zend_hash_add(GLOBAL_CLASS_TABLE, "stdClass", sizeof("stdClass"), &standard_class, sizeof(zend_class_entry), NULL);
}
+#ifdef ZTS
+static void compiler_globals_ctor(zend_compiler_globals *compiler_globals)
+{
+ compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
+ zend_hash_init(compiler_globals->function_table, 100, NULL, (void (*)(void *)) destroy_zend_function, 1);
+ zend_hash_copy(compiler_globals->function_table, global_function_table, NULL, NULL, 0);
+
+ compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
+ zend_hash_init(compiler_globals->class_table, 10, NULL, (void (*)(void *)) destroy_zend_class, 1);
+ zend_hash_copy(compiler_globals->class_table, global_class_table, NULL, NULL, 0);
+}
+
+
+static void compiler_globals_dtor(zend_compiler_globals *compiler_globals)
+{
+ zend_hash_destroy(compiler_globals->function_table);
+ free(compiler_globals->function_table);
+ zend_hash_destroy(compiler_globals->class_table);
+ free(compiler_globals->class_table);
+}
+#endif
+
+
int zend_startup(zend_utility_functions *utility_functions, char **extensions)
{
start_memory_manager();
zend_version_info_length = sizeof(ZEND_CORE_VERSION_INFO)-1;
/* Prepare data structures */
+#ifndef ZTS
zend_startup_constants();
- CG(function_table) = (HashTable *) malloc(sizeof(HashTable));
- CG(class_table) = (HashTable *) malloc(sizeof(HashTable));
- zend_hash_init(CG(function_table), 100, NULL, (void (*)(void *)) destroy_zend_function, 1);
- zend_hash_init(CG(class_table), 10, NULL, (void (*)(void *)) destroy_zend_class, 1);
+#endif
+ GLOBAL_FUNCTION_TABLE = (HashTable *) malloc(sizeof(HashTable));
+ GLOBAL_CLASS_TABLE = (HashTable *) malloc(sizeof(HashTable));
+ zend_hash_init(GLOBAL_FUNCTION_TABLE, 100, NULL, (void (*)(void *)) destroy_zend_function, 1);
+ zend_hash_init(GLOBAL_CLASS_TABLE, 10, NULL, (void (*)(void *)) destroy_zend_class, 1);
register_standard_class();
zend_hash_init(&module_registry, 50, NULL, (void (*)(void *)) module_destructor, 1);
init_resource_plist();
zend_hash_init(&list_destructors, 50, NULL, NULL, 1);
+#ifdef ZTS
+ tsrm_startup(1,1,0);
+ compiler_globals_id = ts_allocate_id(sizeof(zend_compiler_globals), (void (*)(void *)) compiler_globals_ctor, (void (*)(void *)) compiler_globals_dtor);
+ executor_globals_id = ts_allocate_id(sizeof(zend_executor_globals), NULL, NULL);
+ alloc_globals_id = ts_allocate_id(sizeof(zend_alloc_globals), NULL, NULL);
+#endif
+
return SUCCESS;
}
destroy_resource_plist();
zend_hash_destroy(&list_destructors);
zend_hash_destroy(&module_registry);
- zend_hash_destroy(CG(function_table));
- free(CG(function_table));
- zend_hash_destroy(CG(class_table));
- free(CG(class_table));
+ zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
+ free(GLOBAL_FUNCTION_TABLE);
+ zend_hash_destroy(GLOBAL_CLASS_TABLE);
+ free(GLOBAL_CLASS_TABLE);
zend_shutdown_extensions();
free(zend_version_info);
+#ifndef ZTS
zend_shutdown_constants();
+#endif
}
/* this function doesn't check for too many parameters */
ZEND_API int getParameters(int ht, int param_count,...)
{
- void **p = EG(argument_stack).top_element-1;
- int arg_count = (ulong) *p;
+ void **p;
+ int arg_count;
va_list ptr;
zval **param, *param_ptr;
ELS_FETCH();
+ ALS_FETCH();
+
+ p = EG(argument_stack).top_element-1;
+ arg_count = (ulong) *p;
if (param_count>arg_count) {
return FAILURE;
ZEND_API int getParametersArray(int ht, int param_count, zval **argument_array)
{
- void **p = EG(argument_stack).top_element-1;
- int arg_count = (ulong) *p;
+ void **p;
+ int arg_count;
zval *param_ptr;
ELS_FETCH();
+ p = EG(argument_stack).top_element-1;
+ arg_count = (ulong) *p;
+
if (param_count>arg_count) {
return FAILURE;
}
/* this function doesn't check for too many parameters */
ZEND_API int getParametersEx(int param_count,...)
{
- void **p = EG(argument_stack).top_element-1;
- int arg_count = (ulong) *p;
+ void **p;
+ int arg_count;
va_list ptr;
zval ***param;
ELS_FETCH();
+ p = EG(argument_stack).top_element-1;
+ arg_count = (ulong) *p;
+
if (param_count>arg_count) {
return FAILURE;
}
ZEND_API int getParametersArrayEx(int param_count, zval ***argument_array)
{
- void **p = EG(argument_stack).top_element-1;
- int arg_count = (ulong) *p;
+ void **p;
+ int arg_count;
ELS_FETCH();
+ p = EG(argument_stack).top_element-1;
+ arg_count = (ulong) *p;
+
if (param_count>arg_count) {
return FAILURE;
}
ZEND_API int ParameterPassedByReference(int ht, uint n)
{
- void **p = EG(argument_stack).elements+EG(argument_stack).top-1;
- ulong arg_count = (ulong) *p;
+ void **p;
+ ulong arg_count;
zval *arg;
ELS_FETCH();
+ p = EG(argument_stack).elements+EG(argument_stack).top-1;
+ arg_count = (ulong) *p;
+
if (n>arg_count) {
return FAILURE;
}
}
}
module->type = MODULE_PERSISTENT;
- register_module(module);
+ zend_register_module(module);
}
return SUCCESS;
}
/* registers all functions in *library_functions in the function hash */
-int register_functions(zend_function_entry *functions)
+int zend_register_functions(zend_function_entry *functions)
{
zend_function_entry *ptr = functions;
zend_internal_function internal_function;
internal_function.function_name = ptr->fname;
if (!internal_function.handler) {
zend_error(E_CORE_WARNING,"Null function defined as active function");
- unregister_functions(functions,count);
+ zend_unregister_functions(functions,count);
return FAILURE;
}
if (zend_hash_add(CG(function_table), ptr->fname, strlen(ptr->fname)+1, &internal_function, sizeof(zend_internal_function), NULL) == FAILURE) {
}
ptr++;
}
- unregister_functions(functions,count);
+ zend_unregister_functions(functions,count);
return FAILURE;
}
return SUCCESS;
/* count=-1 means erase all functions, otherwise,
* erase the first count functions
*/
-void unregister_functions(zend_function_entry *functions,int count)
+void zend_unregister_functions(zend_function_entry *functions,int count)
{
zend_function_entry *ptr = functions;
int i=0;
}
-ZEND_API int register_module(zend_module_entry *module)
+ZEND_API int zend_register_module(zend_module_entry *module)
{
#if 0
zend_printf("%s: Registering module %d\n",module->name, module->module_number);
#endif
- if (register_functions(module->functions)==FAILURE) {
+ if (zend_register_functions(module->functions)==FAILURE) {
zend_error(E_CORE_WARNING,"%s: Unable to register functions, unable to load",module->name);
return FAILURE;
}
module->module_shutdown_func(module->type, module->module_number);
}
module->module_started=0;
- unregister_functions(module->functions,-1);
+ zend_unregister_functions(module->functions,-1);
#if HAVE_LIBDL
if (module->handle) {
ZEND_API int getThis(zval **this);
ZEND_API int ParameterPassedByReference(int ht, uint n);
-int register_functions(zend_function_entry *functions);
-void unregister_functions(zend_function_entry *functions, int count);
-ZEND_API int register_module(zend_module_entry *module_entry);
+int zend_register_functions(zend_function_entry *functions);
+void zend_unregister_functions(zend_function_entry *functions, int count);
+ZEND_API int zend_register_module(zend_module_entry *module_entry);
zend_class_entry *register_internal_class(zend_class_entry *class_entry);
ZEND_API void wrong_param_count(void);
p->pLast = (mem_header *) NULL;
-/* used by ISAPI and NSAPI */
-
#if ZEND_DEBUG
ZEND_API void *_emalloc(size_t size, char *filename, uint lineno)
#else
#endif
{
mem_header *p;
+ ALS_FETCH();
HANDLE_BLOCK_INTERRUPTIONS();
#endif
{
mem_header *p = (mem_header *) ((char *)ptr - sizeof(mem_header) - PLATFORM_PADDING);
+ ALS_FETCH();
#if ZEND_DEBUG
_mem_block_check(ptr, 1, filename, lineno);
{
mem_header *p = (mem_header *) ((char *)ptr-sizeof(mem_header)-PLATFORM_PADDING);
mem_header *orig = p;
+ ALS_FETCH();
if (!ptr) {
#if ZEND_DEBUG
ZEND_API void start_memory_manager(void)
{
+ ALS_FETCH();
+
AG(phead) = AG(head) = NULL;
#if MEMORY_LIMIT
ZEND_API void shutdown_memory_manager(int silent, int clean_cache)
{
mem_header *p, *t;
+ ALS_FETCH();
p=AG(head);
t=AG(head);
ZEND_API void _full_mem_check(int silent, char *filename, uint lineno)
{
- mem_header *p = AG(head);
+ mem_header *p;
int errors=0;
+ ALS_FETCH();
+
+ p = AG(head);
+
fprintf(stderr,"------------------------------------------------\n");
fprintf(stderr,"Full Memory Check at %s:%d\n", filename, lineno);
#endif
{
mem_header *p = (mem_header *) ((char *)ptr-sizeof(mem_header)-PLATFORM_PADDING);
+ ALS_FETCH();
#if ZEND_DEBUG
_mem_block_check(ptr, 1, filename, lineno);
-void do_fetch_globals(znode *varname)
+void do_fetch_globals(znode *varname CLS_DC)
{
if (!CG(active_op_array)->initialized_globals
&& varname->op_type == IS_CONST
}
-void do_init_string(znode *result)
+void do_init_string(znode *result CLS_DC)
{
zend_op *opline = get_next_op(CG(active_op_array) CLS_CC);
}
if (CG(extended_info)) {
- zend_op *opline = get_next_op(CG(active_op_array));
+ zend_op *opline = get_next_op(CG(active_op_array) CLS_CC);
opline->opcode = ZEND_EXT_NOP;
opline->lineno = function_begin_line;
void fetch_simple_variable(znode *result, znode *varname, int bp CLS_DC);
void do_indirect_references(znode *result, znode *num_references, znode *variable CLS_DC);
void do_fetch_global_or_static_variable(znode *varname, znode *static_assignment, int fetch_type CLS_DC);
-void do_fetch_globals(znode *varname);
+void do_fetch_globals(znode *varname CLS_DC);
void fetch_array_begin(znode *result, znode *varname, znode *first_dim CLS_DC);
void fetch_array_dim(znode *result, znode *parent, znode *dim CLS_DC);
void do_free(znode *op1 CLS_DC);
-void do_init_string(znode *result);
+void do_init_string(znode *result CLS_DC);
void do_add_char(znode *result, znode *op1, znode *op2 CLS_DC);
void do_add_string(znode *result, znode *op1, znode *op2 CLS_DC);
void do_add_variable(znode *result, znode *op1, znode *op2 CLS_DC);
ZEND_API int require_file(zend_file_handle *file_handle CLS_DC);
ZEND_API int require_filename(char *filename CLS_DC);
ZEND_API zend_op_array *compile_files(int mark_as_ref CLS_DC, int file_count, ...);
-ZEND_API zend_op_array *v_compile_files(int mark_as_ref ELS_DC, int file_count, va_list files);
+ZEND_API zend_op_array *v_compile_files(int mark_as_ref CLS_DC, int file_count, va_list files);
ZEND_API zend_op_array *compile_string(zval *source_string CLS_DC);
ZEND_API zend_op_array *compile_filename(zval *filename CLS_DC);
inline int open_file_for_scanning(zend_file_handle *file_handle CLS_DC);
void clean_module_constants(int module_number)
{
+ ELS_FETCH();
+
zend_hash_apply_with_argument(EG(zend_constants), (int (*)(void *,void *)) clean_module_constant, (void *) &module_number);
}
DWORD dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
DWORD dwWindowsMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
#endif
+ ELS_FETCH();
/* ZEND_FIX: Move to PHP */
int zend_shutdown_constants(void)
{
+ ELS_FETCH();
+
zend_hash_destroy(EG(zend_constants));
free(EG(zend_constants));
return SUCCESS;
void clean_non_persistent_constants(void)
{
+ ELS_FETCH();
+
zend_hash_apply(EG(zend_constants), (int (*)(void *)) clean_non_persistent_constant);
}
zend_constant *c;
char *lookup_name = estrndup(name,name_len);
int retval;
+ ELS_FETCH();
zend_str_tolower(lookup_name, name_len);
ZEND_API void zend_register_constant(zend_constant *c)
{
char *lowercase_name = zend_strndup(c->name, c->name_len);
+ ELS_FETCH();
#if 0
printf("Registering constant for module %d\n",c->module_number);
}
EG(active_symbol_table) = calling_symbol_table;
} else { /* ZEND_OVERLOADED_FUNCTION */
- call_overloaded_function(opline->extended_value, &Ts[opline->result.u.var].tmp_var, &EG(regular_list), &EG(persistent_list));
+ call_overloaded_function(opline->extended_value, &Ts[opline->result.u.var].tmp_var, &EG(regular_list), &EG(persistent_list) ELS_CC);
efree(function_being_called);
}
function_state.function = (zend_function *) op_array;
zval **param;
//if (zend_hash_index_find(EG(active_symbol_table), opline->op1.u.constant.value.lval, (void **) ¶m)==FAILURE) {
- if (zend_ptr_stack_get_arg(opline->op1.u.constant.value.lval, (void **) ¶m)==FAILURE) {
+ if (zend_ptr_stack_get_arg(opline->op1.u.constant.value.lval, (void **) ¶m ELS_CC)==FAILURE) {
zend_error(E_NOTICE, "Missing argument %d for %s()\n", opline->op1.u.constant.value.lval, get_active_function_name());
DEC_AI_COUNT();
} else if ((*param)->is_ref) {
zval **param, *assignment_value;
//if (zend_hash_index_find(EG(active_symbol_table), opline->op1.u.constant.value.lval, (void **) ¶m)==FAILURE) {
- if (zend_ptr_stack_get_arg(opline->op1.u.constant.value.lval, (void **) ¶m)==FAILURE) {
+ if (zend_ptr_stack_get_arg(opline->op1.u.constant.value.lval, (void **) ¶m ELS_CC)==FAILURE) {
if (opline->op2.op_type == IS_UNUSED) {
DEC_AI_COUNT();
break;
/* dedicated Zend executor functions - do not use! */
ZEND_API inline void zend_ptr_stack_clear_multiple(ELS_D);
-ZEND_API inline int zend_ptr_stack_get_arg(int requested_arg, void **data);
+ZEND_API inline int zend_ptr_stack_get_arg(int requested_arg, void **data ELS_DC);
#if SUPPORT_INTERACTIVE
void execute_new_code(CLS_D);
-ZEND_API int zend_ptr_stack_get_arg(int requested_arg, void **data)
+ZEND_API int zend_ptr_stack_get_arg(int requested_arg, void **data ELS_DC)
{
void **p = EG(argument_stack).top_element-1;
int arg_count = (ulong) *p;
#include "zend_hash.h"
#include "zend_llist.h"
+
+/* Define ZTS if you want a thread-safe Zend */
#undef ZTS
#ifdef ZTS
-#include "SAPI.h"
+#include "../TSRM/TSRM.h"
extern int compiler_globals_id;
extern int executor_globals_id;
+extern int alloc_globals_id;
#endif
typedef struct _zend_compiler_globals zend_compiler_globals;
{
op_array->type = ZEND_USER_FUNCTION;
#if SUPPORT_INTERACTIVE
- CLS_FETCH();
+ {
+ ELS_FETCH();
- op_array->start_op_number = op_array->end_op_number = op_array->last_executed_op_number = 0;
- op_array->backpatch_count = 0;
- if (EG(interactive)) {
- /* We must avoid a realloc() on the op_array in interactive mode, since pointers to constants
- * will become invalid
- */
- initial_ops_size = 8192;
+ op_array->start_op_number = op_array->end_op_number = op_array->last_executed_op_number = 0;
+ op_array->backpatch_count = 0;
+ if (EG(interactive)) {
+ /* We must avoid a realloc() on the op_array in interactive mode, since pointers to constants
+ * will become invalid
+ */
+ initial_ops_size = 8192;
+ }
}
#endif
}
-static void zend_update_extended_info(zend_op_array *op_array)
+static void zend_update_extended_info(zend_op_array *op_array CLS_DC)
{
zend_op *opline = op_array->opcodes, *end=opline+op_array->last;
}
opline++;
}
- opline = get_next_op(op_array);
+ opline = get_next_op(op_array CLS_CC);
opline->opcode = ZEND_EXT_STMT;
opline->op1.op_type = IS_UNUSED;
opline->op2.op_type = IS_UNUSED;
return 0;
}
if (CG(extended_info)) {
- zend_update_extended_info(op_array);
+ zend_update_extended_info(op_array CLS_CC);
}
if (CG(handle_op_arrays)) {
zend_llist_apply_with_argument(&zend_extensions, (void (*)(void *, void *)) zend_extension_op_array_handler, op_array);