1
0
mirror of https://github.com/php/php-src.git synced 2026-03-29 11:42:17 +02:00

- Fix up the new operator a bit more.

This commit is contained in:
Andi Gutmans
1999-07-27 17:30:16 +00:00
parent a99ccfc6ef
commit 88322d2ea0

View File

@@ -152,24 +152,28 @@ static inline zval **_get_zval_ptr_ptr(znode *node, temp_variable *Ts ELS_DC)
}
}
static inline zval *_get_object_zval_ptr(znode *node, temp_variable *Ts, int *should_free ELS_DC)
static inline zval *_get_object_zval_ptr(znode *node, temp_variable *Ts, int *should_free, zval ***object_ptr_ptr ELS_DC)
{
switch(node->op_type) {
case IS_TMP_VAR:
*should_free = 1;
*object_ptr_ptr = NULL;
return &Ts[node->u.var].tmp_var;
break;
case IS_VAR:
if (Ts[node->u.var].var) {
PZVAL_UNLOCK(*Ts[node->u.var].var);
*should_free = 0;
return *Ts[node->u.var].var;
*object_ptr_ptr = Ts[node->u.var].var;
return **object_ptr_ptr;
} else {
*should_free = 1;
*object_ptr_ptr = NULL;
return NULL;
}
break;
case IS_UNUSED:
*object_ptr_ptr = NULL;
return NULL;
break;
#if DEBUG_ZEND
@@ -862,6 +866,10 @@ static void call_overloaded_function(int arg_count, zval *return_value, HashTabl
# define free_alloca(p) efree(p)
#endif
typedef struct _object_info {
zval *ptr;
zval **ptr_ptr;
} object_info;
void execute(zend_op_array *op_array ELS_DC)
{
@@ -873,7 +881,7 @@ void execute(zend_op_array *op_array ELS_DC)
zend_function_state function_state;
HashTable *calling_symbol_table;
zend_function *function_being_called=NULL;
zval *object_ptr=NULL;
object_info object;
#if !defined (__GNUC__) || __GNUC__ < 2
temp_variable *Ts = (temp_variable *) do_alloca(sizeof(temp_variable)*op_array->T);
#else
@@ -887,6 +895,7 @@ void execute(zend_op_array *op_array ELS_DC)
}
#endif
object.ptr = NULL;
EG(opline_ptr) = &opline;
function_state.function = (zend_function *) op_array;
@@ -1295,7 +1304,8 @@ binary_assign_op_addr: {
zval tmp;
zend_ptr_stack_push(&EG(arg_types_stack), function_being_called);
zend_ptr_stack_push(&EG(arg_types_stack), object_ptr);
zend_ptr_stack_push(&EG(arg_types_stack), object.ptr);
zend_ptr_stack_push(&EG(arg_types_stack), object.ptr_ptr);
if (opline->extended_value & ZEND_CTOR_CALL) {
/* constructor call */
@@ -1325,25 +1335,26 @@ binary_assign_op_addr: {
}
active_function_table = &ce->function_table;
if (zend_hash_find(EG(active_symbol_table), "this", sizeof("this"), (void **) &object_ptr_ptr)==FAILURE) {
object_ptr=NULL;
object.ptr=NULL;
} else {
object_ptr = *object_ptr_ptr;
object.ptr = *object_ptr_ptr;
object.ptr_ptr = object_ptr_ptr;
}
} else { /* used for member function calls */
object_ptr = _get_object_zval_ptr(&opline->op1, Ts, &free_op1 ELS_CC);
object.ptr = _get_object_zval_ptr(&opline->op1, Ts, &free_op1, &object.ptr_ptr ELS_CC);
if (!object_ptr
|| ((object_ptr->type==IS_OBJECT) && (object_ptr->value.obj.ce->handle_function_call))) { /* overloaded function call */
if (!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 = IS_METHOD;
if (object_ptr) {
if (object.ptr) {
zend_property_reference property_reference;
property_reference.object = object_ptr;
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));
@@ -1356,13 +1367,13 @@ binary_assign_op_addr: {
goto overloaded_function_call_cont;
}
if (object_ptr->type != IS_OBJECT) {
if (object.ptr->type != IS_OBJECT) {
zend_error(E_ERROR, "Call to a member function on a non-object");
}
active_function_table = &(object_ptr->value.obj.ce->function_table);
active_function_table = &(object.ptr->value.obj.ce->function_table);
}
} else { /* function pointer */
object_ptr = NULL;
object.ptr = NULL;
active_function_table = EG(function_table);
}
if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) {
@@ -1393,7 +1404,7 @@ do_fcall_common:
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), (object_ptr?object_ptr:NULL));
((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]);*/
@@ -1406,28 +1417,29 @@ do_fcall_common:
calling_symbol_table = EG(active_symbol_table);
EG(active_symbol_table) = function_state.function_symbol_table;
if (opline->opcode==ZEND_DO_FCALL_BY_NAME
&& object_ptr
&& object.ptr
&& function_being_called->type!=ZEND_OVERLOADED_FUNCTION) {
zval **this_ptr;
zval *tmp;
zend_hash_update_ptr(function_state.function_symbol_table, "this", sizeof("this"), NULL, sizeof(zval *), (void **) &this_ptr);
if (!PZVAL_IS_REF(object_ptr)) {
if (!PZVAL_IS_REF(object.ptr)) {
/* break it away */
object_ptr->refcount--;
if (object_ptr->refcount>0) {
object.ptr->refcount--;
if (object.ptr->refcount>0) {
tmp = (zval *) emalloc(sizeof(zval));
*tmp = *object_ptr;
*tmp = *object.ptr;
zendi_zval_copy_ctor(*tmp);
object_ptr = tmp;
object.ptr = tmp;
*object.ptr_ptr = tmp;
}
object_ptr->refcount = 1;
object_ptr->EA.is_ref = 1;
object_ptr->EA.locks = 0;
object.ptr->refcount = 1;
object.ptr->EA.is_ref = 1;
object.ptr->EA.locks = 0;
}
*this_ptr = object_ptr;
object_ptr->refcount++;
object_ptr = NULL;
*this_ptr = object.ptr;
object.ptr->refcount++;
object.ptr = NULL;
}
original_return_value = EG(return_value);
EG(return_value) = &Ts[opline->result.u.var].tmp_var;
@@ -1450,7 +1462,8 @@ do_fcall_common:
efree(function_being_called);
}
if (opline->opcode == ZEND_DO_FCALL_BY_NAME) {
object_ptr = zend_ptr_stack_pop(&EG(arg_types_stack));
object.ptr_ptr = zend_ptr_stack_pop(&EG(arg_types_stack));
object.ptr = zend_ptr_stack_pop(&EG(arg_types_stack));
function_being_called = zend_ptr_stack_pop(&EG(arg_types_stack));
}
function_state.function = (zend_function *) op_array;