From 741b816136830af36a54fb9d4c92e4ac0a12ed57 Mon Sep 17 00:00:00 2001 From: Zeev Suraski Date: Fri, 28 May 1999 12:06:59 +0000 Subject: [PATCH] * Support getThis() for internal functions. * Fix 'new object or die' and AiCount issue thoroughly (earlier fix didn't work with the optimizer). * Add new macros for standardized definition of classes. * Only report AiCount problems if shutdown was not silent. --- Zend/zend.h | 5 +++-- Zend/zend_API.c | 50 +++++++++++++++++++---------------------- Zend/zend_API.h | 29 +++++++++++++++++++++--- Zend/zend_alloc.c | 2 +- Zend/zend_compile.c | 4 ++++ Zend/zend_compile.h | 3 +++ Zend/zend_execute.c | 8 +++---- Zend/zend_execute_API.c | 2 +- 8 files changed, 64 insertions(+), 39 deletions(-) diff --git a/Zend/zend.h b/Zend/zend.h index a0e375e53b..6616c4efcb 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -56,8 +56,8 @@ #include "zend_llist.h" -#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, HashTable *list, HashTable *plist -#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, list, plist +#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, HashTable *list, HashTable *plist, zval *this_ptr +#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, list, plist, this_ptr /* * zval @@ -121,6 +121,7 @@ struct _zend_class_entry { HashTable function_table; HashTable default_properties; + zend_function_entry *builtin_functions; /* handlers */ void (*handle_function_call)(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference); diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 49ed26dbe9..492289beda 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -161,22 +161,6 @@ ZEND_API int getParametersArrayEx(int param_count, zval ***argument_array) } -ZEND_API int getThis(zval **this_ptr) -{ - /* NEEDS TO BE IMPLEMENTED FOR ZEND */ - /* - zval *data; - - if (zend_hash_find(function_state.calling_symbol_table, "this", sizeof("this"), (void **)&data) == FAILURE) { - return FAILURE; - } - - *this = data; - */ - return SUCCESS; -} - - ZEND_API int ParameterPassedByReference(int ht, uint n) { void **p; @@ -609,13 +593,17 @@ ZEND_API int _register_list_destructors(void (*list_destructor)(void *), void (* /* registers all functions in *library_functions in the function hash */ -int zend_register_functions(zend_function_entry *functions) +int zend_register_functions(zend_function_entry *functions, HashTable *function_table) { zend_function_entry *ptr = functions; zend_internal_function internal_function; int count=0,unload=0; + HashTable *target_function_table = function_table; CLS_FETCH(); + if (!target_function_table) { + target_function_table = CG(function_table); + } internal_function.type = ZEND_INTERNAL_FUNCTION; while (ptr->fname) { @@ -624,10 +612,10 @@ int zend_register_functions(zend_function_entry *functions) internal_function.function_name = ptr->fname; if (!internal_function.handler) { zend_error(E_CORE_WARNING,"Null function defined as active function"); - zend_unregister_functions(functions,count); + zend_unregister_functions(functions, count, target_function_table); return FAILURE; } - if (zend_hash_add(CG(function_table), ptr->fname, strlen(ptr->fname)+1, &internal_function, sizeof(zend_internal_function), NULL) == FAILURE) { + if (zend_hash_add(target_function_table, ptr->fname, strlen(ptr->fname)+1, &internal_function, sizeof(zend_internal_function), NULL) == FAILURE) { unload=1; break; } @@ -636,12 +624,12 @@ int zend_register_functions(zend_function_entry *functions) } if (unload) { /* before unloading, display all remaining bad function in the module */ while (ptr->fname) { - if (zend_hash_exists(CG(function_table), ptr->fname, strlen(ptr->fname)+1)) { - zend_error(E_CORE_WARNING,"Module load failed - duplicate function name - %s",ptr->fname); + if (zend_hash_exists(target_function_table, ptr->fname, strlen(ptr->fname)+1)) { + zend_error(E_CORE_WARNING, "Function registration failed - duplicate name - %s",ptr->fname); } ptr++; } - zend_unregister_functions(functions,count); + zend_unregister_functions(functions, count, target_function_table); return FAILURE; } return SUCCESS; @@ -650,20 +638,24 @@ int zend_register_functions(zend_function_entry *functions) /* count=-1 means erase all functions, otherwise, * erase the first count functions */ -void zend_unregister_functions(zend_function_entry *functions,int count) +void zend_unregister_functions(zend_function_entry *functions, int count, HashTable *function_table) { zend_function_entry *ptr = functions; int i=0; + HashTable *target_function_table = function_table; CLS_FETCH(); + if (!target_function_table) { + target_function_table = CG(function_table); + } while (ptr->fname) { if (count!=-1 && i>=count) { break; } #if 0 - zend_printf("Unregistering %s()\n",ptr->fname); + zend_printf("Unregistering %s()\n", ptr->fname); #endif - zend_hash_del(CG(function_table),ptr->fname,strlen(ptr->fname)+1); + zend_hash_del(target_function_table, ptr->fname, strlen(ptr->fname)+1); ptr++; i++; } @@ -675,7 +667,7 @@ 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 (module->functions && zend_register_functions(module->functions)==FAILURE) { + if (module->functions && zend_register_functions(module->functions, NULL)==FAILURE) { zend_error(E_CORE_WARNING,"%s: Unable to register functions, unable to load",module->name); return FAILURE; } @@ -706,7 +698,7 @@ void module_destructor(zend_module_entry *module) } module->module_started=0; if (module->functions) { - zend_unregister_functions(module->functions,-1); + zend_unregister_functions(module->functions, -1, NULL); } #if HAVE_LIBDL @@ -779,6 +771,10 @@ ZEND_API zend_class_entry *register_internal_class(zend_class_entry *class_entry zend_hash_update(CG(class_table), lowercase_name, class_entry->name_length+1, class_entry, sizeof(zend_class_entry), (void **) ®ister_class); free(lowercase_name); + + if (class_entry->builtin_functions) { + zend_register_functions(class_entry->builtin_functions, &class_entry->function_table); + } return register_class; } diff --git a/Zend/zend_API.h b/Zend/zend_API.h index e312e5b214..c1a3edb486 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -28,6 +28,28 @@ #define ZEND_FE(name, arg_types) ZEND_NAMED_FE(name, zend_if_##name, arg_types) +#define INIT_CLASS_ENTRY(class_container, class_name, functions) \ + { \ + class_container.name = strdup(class_name); \ + class_container.name_length = sizeof(class_name)-1; \ + class_container.builtin_functions = functions; \ + class_container.handle_function_call = NULL; \ + class_container.handle_property_get = NULL; \ + class_container.handle_property_set = NULL; \ + } + +#define INIT_OVERLOADED_CLASS_ENTRY(class_container, class_name, functions, handle_fcall, handle_propget, handle_propset) \ + { \ + class_container.name = strdup(class_name); \ + class_container.name_length = sizeof(class_name)-1; \ + class_container.builtin_functions = functions; \ + class_container.handle_function_call = handle_fcall; \ + class_container.handle_property_get = handle_propget; \ + class_container.handle_property_set = handle_propset; \ + } + + + int zend_next_free_module(void); ZEND_API int getParameters(int ht, int param_count,...); @@ -35,17 +57,18 @@ ZEND_API int getParametersArray(int ht, int param_count, zval **argument_array); ZEND_API int getParametersEx(int param_count,...); ZEND_API int getParametersArrayEx(int param_count, zval ***argument_array); -ZEND_API int getThis(zval **this_ptr); ZEND_API int ParameterPassedByReference(int ht, uint n); -int zend_register_functions(zend_function_entry *functions); -void zend_unregister_functions(zend_function_entry *functions, int count); +int zend_register_functions(zend_function_entry *functions, HashTable *function_table); +void zend_unregister_functions(zend_function_entry *functions, int count, HashTable *function_table); ZEND_API int zend_register_module(zend_module_entry *module_entry); ZEND_API zend_class_entry *register_internal_class(zend_class_entry *class_entry); ZEND_API zend_module_entry *zend_get_module(int module_number); ZEND_API void wrong_param_count(void); +#define getThis() (this_ptr) + #define WRONG_PARAM_COUNT { wrong_param_count(); return; } #define WRONG_PARAM_COUNT_WITH_RETVAL(ret) { wrong_param_count(); return ret; } #define ARG_COUNT(ht) (ht) diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index e82948acf6..8f022e1325 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -389,7 +389,7 @@ ZEND_API void shutdown_memory_manager(int silent, int clean_cache) if (had_leaks) { ELS_FETCH(); - if (EG(AiCount)!=0) { + if (EG(AiCount)!=0 && !silent) { fprintf(stderr, "AiCount did not zero out: %d\n", EG(AiCount)); } } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 5224033258..fac2c1db28 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -734,6 +734,7 @@ void do_begin_dynamic_function_call(znode *function_name CLS_DC) opline->opcode = ZEND_INIT_FCALL_BY_NAME; opline->op2 = *function_name; + opline->extended_value = 0; SET_UNUSED(opline->op1); } zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(unsigned char *)); @@ -749,6 +750,7 @@ void do_begin_class_member_function_call(znode *class_name, znode *function_name zend_str_tolower(class_name->u.constant.value.str.val, class_name->u.constant.value.str.len); opline->op1 = *class_name; opline->op2 = *function_name; + opline->extended_value = ZEND_MEMBER_FUNC_CALL; zval_copy_ctor(&opline->op2.u.constant); zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(unsigned char *)); } @@ -883,6 +885,7 @@ void do_early_binding(CLS_D) opline->opcode = ZEND_NOP; SET_UNUSED(opline->op1); SET_UNUSED(opline->op2); + //CG(active_op_array)->last--; } @@ -1297,6 +1300,7 @@ void do_begin_new_object(znode *result, znode *variable, znode *new_token, znode opline->opcode = ZEND_INIT_FCALL_BY_NAME; opline->op1 = *result; opline->op2 = *class_name; + opline->extended_value = ZEND_MEMBER_FUNC_CALL | ZEND_CTOR_CALL; zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(unsigned char *)); } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index e48acf4f2f..a439e352fe 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -535,4 +535,7 @@ int zendlex(znode *zendlval CLS_DC); #define ZEND_FETCH_STANDARD 0 #define ZEND_FETCH_NO_AI_COUNT 1 +#define ZEND_MEMBER_FUNC_CALL 1<<0 +#define ZEND_CTOR_CALL 1<<1 + #endif /* _COMPILE_H */ diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index b49c69f05a..f2623b4410 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -793,7 +793,7 @@ static void call_overloaded_function(int arg_count, zval *return_value, HashTabl zend_property_reference *property_reference; zend_stack_top(&EG(overloaded_objects_stack), (void **) &property_reference); - (*(property_reference->object))->value.obj.ce->handle_function_call(arg_count, return_value, list, plist, property_reference); + (*(property_reference->object))->value.obj.ce->handle_function_call(arg_count, return_value, list, plist, *property_reference->object, property_reference); //(*(property_reference->object))->value.obj.ce->handle_function_call(NULL, NULL, NULL, NULL, NULL); zend_llist_destroy(&property_reference->elements_list); @@ -1226,9 +1226,7 @@ binary_assign_op_addr: { HashTable *active_function_table; zval tmp; - if ((opline>EG(active_op_array)->opcodes) - && opline->op1.op_type==IS_VAR - && (opline-1)->opcode == ZEND_JMP_NO_CTOR) { + if (opline->extended_value & ZEND_CTOR_CALL) { /* constructor call */ EG(AiCount)++; /* for op1 */ if (opline->op2.op_type==IS_VAR) { @@ -1325,7 +1323,7 @@ overloaded_function_call_cont: zend_ptr_stack_push(&EG(argument_stack), (void *) opline->extended_value); if (function_state.function->type==ZEND_INTERNAL_FUNCTION) { var_uninit(&Ts[opline->result.u.var].tmp_var); - ((zend_internal_function *) function_state.function)->handler(opline->extended_value, &Ts[opline->result.u.var].tmp_var, &EG(regular_list), &EG(persistent_list)); + ((zend_internal_function *) function_state.function)->handler(opline->extended_value, &Ts[opline->result.u.var].tmp_var, &EG(regular_list), &EG(persistent_list), (object_ptr?*object_ptr:NULL)); } else if (function_state.function->type==ZEND_USER_FUNCTION) { if (EG(symtable_cache_ptr)>=EG(symtable_cache)) { //printf("Cache hit! Reusing %x\n", symtable_cache[symtable_cache_ptr]); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 6f20f976b0..687068cd76 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -335,7 +335,7 @@ int call_user_function(HashTable *function_table, zval *object, zval *function_n EG(return_value)=original_return_value; EG(opline_ptr) = original_opline_ptr; } else { - ((zend_internal_function *) function_state.function)->handler(param_count, retval, &EG(regular_list), &EG(persistent_list)); + ((zend_internal_function *) function_state.function)->handler(param_count, retval, &EG(regular_list), &EG(persistent_list), object); } zend_ptr_stack_clear_multiple(ELS_C); EG(function_state_ptr) = original_function_state_ptr; -- 2.40.0