From: Andi Gutmans <andi@php.net>
Date: Tue, 27 Jul 1999 17:30:16 +0000 (+0000)
Subject: - Fix up the new operator a bit more.
X-Git-Tag: php-4.0b2~97
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=88322d2ea018cdc92300833c62cc1e4c78092bb4;p=php

- Fix up the new operator a bit more.
---

diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 8751982264..d3cad93a10 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -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;