summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend.h2
-rw-r--r--Zend/zend_compile.h11
-rw-r--r--Zend/zend_execute.c88
-rw-r--r--Zend/zend_execute.h3
-rw-r--r--Zend/zend_execute_API.c2
-rw-r--r--Zend/zend_globals.h1
-rw-r--r--Zend/zend_operators.c6
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 {