summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend.h5
-rw-r--r--Zend/zend_API.c50
-rw-r--r--Zend/zend_API.h29
-rw-r--r--Zend/zend_alloc.c2
-rw-r--r--Zend/zend_compile.c4
-rw-r--r--Zend/zend_compile.h3
-rw-r--r--Zend/zend_execute.c8
-rw-r--r--Zend/zend_execute_API.c2
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 **) &register_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;