diff options
-rw-r--r-- | Zend/zend.h | 2 | ||||
-rw-r--r-- | Zend/zend_compile.h | 11 | ||||
-rw-r--r-- | Zend/zend_execute.c | 88 | ||||
-rw-r--r-- | Zend/zend_execute.h | 3 | ||||
-rw-r--r-- | Zend/zend_execute_API.c | 2 | ||||
-rw-r--r-- | Zend/zend_globals.h | 1 | ||||
-rw-r--r-- | Zend/zend_operators.c | 6 |
7 files changed, 51 insertions, 62 deletions
diff --git a/Zend/zend.h b/Zend/zend.h index d138caee74..343ba1bb31 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -186,7 +186,7 @@ typedef struct _zend_function_entry { typedef struct _zend_property_reference { int type; /* read, write or r/w */ zval *object; - zend_llist elements_list; + zend_llist *elements_list; } zend_property_reference; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index dcd399fcf0..73076ae1eb 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -130,6 +130,16 @@ typedef struct _zend_internal_function { } zend_internal_function; +typedef struct _zend_overloaded_function { + zend_uchar type; /* MUST be the first element of this struct! */ + + zend_uchar *arg_types; /* MUST be the second element of this struct */ + char *function_name; /* MUST be the third element of this struct */ + + zend_uint var; +} zend_overloaded_function; + + typedef union _zend_function { zend_uchar type; /* MUST be the first element of this struct! */ struct { @@ -140,6 +150,7 @@ typedef union _zend_function { zend_op_array op_array; zend_internal_function internal_function; + zend_overloaded_function overloaded_function; } zend_function; diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 675b641012..7bf0e106c8 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -54,9 +54,9 @@ /* Prototypes */ -static zval get_overloaded_property(ELS_D); -static void set_overloaded_property(zval *value ELS_DC); -static void call_overloaded_function(int arg_count, zval *return_value ELS_DC); +static zval get_overloaded_property(temp_variable *T ELS_DC); +static void set_overloaded_property(temp_variable *T, zval *value ELS_DC); +static void call_overloaded_function(temp_variable *T, int arg_count, zval *return_value ELS_DC); static void zend_fetch_var_address(znode *result, znode *op1, znode *op2, temp_variable *Ts, int type ELS_DC); static void zend_fetch_dimension_address(znode *result, znode *op1, znode *op2, temp_variable *Ts, int type ELS_DC); static void zend_fetch_property_address(znode *result, znode *op1, znode *op2, temp_variable *Ts, int type ELS_DC); @@ -96,7 +96,7 @@ static inline zval *_get_zval_ptr(znode *node, temp_variable *Ts, int *should_fr switch (Ts[node->u.var].EA.type) { case IS_OVERLOADED_OBJECT: - Ts[node->u.var].tmp_var = get_overloaded_property(ELS_C); + Ts[node->u.var].tmp_var = get_overloaded_property(&Ts[node->u.var] ELS_CC); Ts[node->u.var].tmp_var.refcount=1; Ts[node->u.var].tmp_var.is_ref=1; return &Ts[node->u.var].tmp_var; @@ -262,7 +262,7 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2 if (!variable_ptr_ptr) { switch (Ts[op1->u.var].EA.type) { case IS_OVERLOADED_OBJECT: - set_overloaded_property(value ELS_CC); + set_overloaded_property(&Ts[op1->u.var], value ELS_CC); if (type == IS_TMP_VAR) { zval_dtor(value); } @@ -623,7 +623,6 @@ static void zend_fetch_dimension_address(znode *result, znode *op1, znode *op2, if (container_ptr == NULL) { - zend_property_reference *property_reference; zend_overloaded_element overloaded_element; if (Ts[op1->u.var].EA.type == IS_STRING_OFFSET) { @@ -649,9 +648,8 @@ static void zend_fetch_dimension_address(znode *result, znode *op1, znode *op2, zval_copy_ctor(&overloaded_element.element); } - zend_stack_top(&EG(overloaded_objects_stack), (void **) &property_reference); - - zend_llist_add_element(&property_reference->elements_list, &overloaded_element); + Ts[result->u.var].EA = Ts[op1->u.var].EA; + zend_llist_add_element(Ts[result->u.var].EA.data.overloaded_element.elements_list, &overloaded_element); Ts[result->u.var].EA.type = IS_OVERLOADED_OBJECT; *retval = NULL; @@ -786,7 +784,6 @@ static void zend_fetch_property_address(znode *result, znode *op1, znode *op2, t if (container_ptr == NULL) { - zend_property_reference *property_reference; zend_overloaded_element overloaded_element; if (Ts[op1->u.var].EA.type == IS_STRING_OFFSET) { @@ -812,9 +809,8 @@ static void zend_fetch_property_address(znode *result, znode *op1, znode *op2, t zval_copy_ctor(&overloaded_element.element); } - zend_stack_top(&EG(overloaded_objects_stack), (void **) &property_reference); - - zend_llist_add_element(&property_reference->elements_list, &overloaded_element); + Ts[result->u.var].EA = Ts[op1->u.var].EA; + zend_llist_add_element(Ts[result->u.var].EA.data.overloaded_element.elements_list, &overloaded_element); Ts[result->u.var].EA.type = IS_OVERLOADED_OBJECT; *retval = NULL; @@ -830,19 +826,18 @@ static void zend_fetch_property_address(znode *result, znode *op1, znode *op2, t if (container->type == IS_OBJECT && container->value.obj.ce->handle_property_get) { - zend_property_reference property_reference; zend_overloaded_element overloaded_element; - property_reference.object = container; - property_reference.type = type; - zend_llist_init(&property_reference.elements_list, sizeof(zend_overloaded_element), NULL, 0); + Ts[result->u.var].EA.data.overloaded_element.object = container; + Ts[result->u.var].EA.data.overloaded_element.type = type; + Ts[result->u.var].EA.data.overloaded_element.elements_list = (zend_llist *) emalloc(sizeof(zend_llist)); + zend_llist_init(Ts[result->u.var].EA.data.overloaded_element.elements_list, sizeof(zend_overloaded_element), NULL, 0); overloaded_element.element = *get_zval_ptr(op2, Ts, &free_op2, type); overloaded_element.type = OE_IS_OBJECT; if (!free_op2) { zval_copy_ctor(&overloaded_element.element); } - zend_llist_add_element(&property_reference.elements_list, &overloaded_element); - zend_stack_push(&EG(overloaded_objects_stack), &property_reference, sizeof(zend_property_reference)); + zend_llist_add_element(Ts[result->u.var].EA.data.overloaded_element.elements_list, &overloaded_element); Ts[result->u.var].EA.type = IS_OVERLOADED_OBJECT; *retval = NULL; return; @@ -897,43 +892,31 @@ static void zend_fetch_property_address(znode *result, znode *op1, znode *op2, t } -static zval get_overloaded_property(ELS_D) +static zval get_overloaded_property(temp_variable *T ELS_DC) { - zend_property_reference *property_reference; zval result; - zend_stack_top(&EG(overloaded_objects_stack), (void **) &property_reference); - result = (property_reference->object)->value.obj.ce->handle_property_get(property_reference); - - zend_llist_destroy(&property_reference->elements_list); + result = (T->EA.data.overloaded_element.object)->value.obj.ce->handle_property_get(&T->EA.data.overloaded_element); - zend_stack_del_top(&EG(overloaded_objects_stack)); + zend_llist_destroy(T->EA.data.overloaded_element.elements_list); + efree(T->EA.data.overloaded_element.elements_list); return result; } -static void set_overloaded_property(zval *value ELS_DC) +static void set_overloaded_property(temp_variable *T, zval *value ELS_DC) { - zend_property_reference *property_reference; - - zend_stack_top(&EG(overloaded_objects_stack), (void **) &property_reference); - (property_reference->object)->value.obj.ce->handle_property_set(property_reference, value); - - zend_llist_destroy(&property_reference->elements_list); - - zend_stack_del_top(&EG(overloaded_objects_stack)); + (T->EA.data.overloaded_element.object)->value.obj.ce->handle_property_set(&T->EA.data.overloaded_element, value); + zend_llist_destroy(T->EA.data.overloaded_element.elements_list); + efree(T->EA.data.overloaded_element.elements_list); } -static void call_overloaded_function(int arg_count, zval *return_value ELS_DC) +static void call_overloaded_function(temp_variable *T, int arg_count, zval *return_value ELS_DC) { - 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, property_reference->object, 1 ELS_CC, property_reference); - zend_llist_destroy(&property_reference->elements_list); - - zend_stack_del_top(&EG(overloaded_objects_stack)); + (T->EA.data.overloaded_element.object)->value.obj.ce->handle_function_call(arg_count, return_value, T->EA.data.overloaded_element.object, 1 ELS_CC, &T->EA.data.overloaded_element); + zend_llist_destroy(T->EA.data.overloaded_element.elements_list); + efree(T->EA.data.overloaded_element.elements_list); } @@ -1520,31 +1503,28 @@ binary_assign_op_addr: { if ((!object.ptr && Ts[opline->op1.u.var].EA.type==IS_OVERLOADED_OBJECT) || ((object.ptr && object.ptr->type==IS_OBJECT) && (object.ptr->value.obj.ce->handle_function_call))) { /* overloaded function call */ zend_overloaded_element overloaded_element; - zend_property_reference *property_reference; overloaded_element.element = *function_name; overloaded_element.type = OE_IS_METHOD; if (object.ptr) { - zend_property_reference property_reference; - - property_reference.object = object.ptr; - property_reference.type = BP_VAR_NA; - zend_llist_init(&property_reference.elements_list, sizeof(zend_overloaded_element), NULL, 0); - zend_stack_push(&EG(overloaded_objects_stack), &property_reference, sizeof(zend_property_reference)); + Ts[opline->op1.u.var].EA.data.overloaded_element.object = object.ptr; + Ts[opline->op1.u.var].EA.data.overloaded_element.type = BP_VAR_NA; + Ts[opline->op1.u.var].EA.data.overloaded_element.elements_list = (zend_llist *) emalloc(sizeof(zend_llist)); + zend_llist_init(Ts[opline->op1.u.var].EA.data.overloaded_element.elements_list, sizeof(zend_overloaded_element), NULL, 0); } - zend_stack_top(&EG(overloaded_objects_stack), (void **) &property_reference); - zend_llist_add_element(&property_reference->elements_list, &overloaded_element); + zend_llist_add_element(Ts[opline->op1.u.var].EA.data.overloaded_element.elements_list, &overloaded_element); fbc = (zend_function *) emalloc(sizeof(zend_function)); fbc->type = ZEND_OVERLOADED_FUNCTION; fbc->common.arg_types = NULL; + fbc->overloaded_function.var = opline->op1.u.var; goto overloaded_function_call_cont; } if (!object.ptr || object.ptr->type != IS_OBJECT) { zend_error(E_ERROR, "Call to a member function on a non-object"); } - object.ptr->refcount++; /* For this pointer */ + object.ptr->refcount++; /* For $this pointer */ active_function_table = &(object.ptr->value.obj.ce->function_table); } } else { /* function pointer */ @@ -1648,7 +1628,7 @@ do_fcall_common: } else { /* ZEND_OVERLOADED_FUNCTION */ ALLOC_ZVAL(Ts[opline->result.u.var].var.ptr); INIT_ZVAL(*(Ts[opline->result.u.var].var.ptr)); - call_overloaded_function(opline->extended_value, Ts[opline->result.u.var].var.ptr ELS_CC); + call_overloaded_function(&Ts[fbc->overloaded_function.var], opline->extended_value, Ts[opline->result.u.var].var.ptr ELS_CC); efree(fbc); if (!return_value_used) { zval_ptr_dtor(&Ts[opline->result.u.var].var.ptr); diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 35864727ee..aeb79b7f2c 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -38,8 +38,7 @@ typedef union _temp_variable { zval *str; int offset; } str_offset; -// struct { -// } overloaded_object; + zend_property_reference overloaded_element; } data; unsigned char type; diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 1daea3ce17..f691ac8ffc 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -85,7 +85,6 @@ void init_executor(CLS_D ELS_DC) EG(uninitialized_zval_ptr)=&EG(uninitialized_zval); EG(error_zval_ptr)=&EG(error_zval); zend_ptr_stack_init(&EG(arg_types_stack)); - zend_stack_init(&EG(overloaded_objects_stack)); /* destroys stack frame, therefore makes core dumps worthless */ #if 0&&ZEND_DEBUG original_sigsegv_handler = signal(SIGSEGV, zend_handle_sigsegv); @@ -123,7 +122,6 @@ void shutdown_executor(ELS_D) { zval_dtor(&EG(global_return_value)); zend_ptr_stack_destroy(&EG(arg_types_stack)); - zend_stack_destroy(&EG(overloaded_objects_stack)); while (EG(symtable_cache_ptr)>=EG(symtable_cache)) { zend_hash_destroy(*EG(symtable_cache_ptr)); diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 1a68f6c587..f41753d47c 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -131,7 +131,6 @@ struct _zend_executor_globals { zend_function_state *function_state_ptr; zend_ptr_stack arg_types_stack; - zend_stack overloaded_objects_stack; /* for global return() support */ zval *global_return_value_ptr; diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 0a2cc35148..60ce076a38 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -1047,6 +1047,7 @@ ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2) return FAILURE; } if (result->type == IS_LONG) { + result->type = IS_BOOL; if (result->value.lval < 0) { result->value.lval = 1; } else { @@ -1055,7 +1056,7 @@ ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2) return SUCCESS; } if (result->type == IS_DOUBLE) { - result->type = IS_LONG; + result->type = IS_BOOL; if (result->value.dval < 0) { result->value.lval = 1; } else { @@ -1074,6 +1075,7 @@ ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2) return FAILURE; } if (result->type == IS_LONG) { + result->type = IS_BOOL; if (result->value.lval <= 0) { result->value.lval = 1; } else { @@ -1082,7 +1084,7 @@ ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2) return SUCCESS; } if (result->type == IS_DOUBLE) { - result->type = IS_LONG; + result->type = IS_BOOL; if (result->value.dval <= 0) { result->value.lval = 1; } else { |