#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
HashTable function_table;
HashTable default_properties;
+ zend_function_entry *builtin_functions;
/* handlers */
void (*handle_function_call)(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference);
}
-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;
/* 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) {
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;
}
}
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;
/* 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++;
}
#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;
}
}
module->module_started=0;
if (module->functions) {
- zend_unregister_functions(module->functions,-1);
+ zend_unregister_functions(module->functions, -1, NULL);
}
#if HAVE_LIBDL
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;
}
#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,...);
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)
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));
}
}
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 *));
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 *));
}
opline->opcode = ZEND_NOP;
SET_UNUSED(opline->op1);
SET_UNUSED(opline->op2);
+ //CG(active_op_array)->last--;
}
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 *));
}
#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 */
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);
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) {
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]);
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;