]> granicus.if.org Git - php/commitdiff
- Made things work again (Thies, everybody - please check the latest CVS and see...
authorZeev Suraski <zeev@php.net>
Sun, 19 Dec 1999 18:54:40 +0000 (18:54 +0000)
committerZeev Suraski <zeev@php.net>
Sun, 19 Dec 1999 18:54:40 +0000 (18:54 +0000)
  still getting any problems)
- Changed the interface of call_user_function_ex() to support returning of references

Zend/zend.h
Zend/zend_API.h
Zend/zend_compile.c
Zend/zend_execute.c
Zend/zend_execute.h
Zend/zend_execute_API.c
Zend/zend_globals.h

index 8533a2d5c14ddab3ecd02bb7992571b67d8fb511..0f41887a583c5ec309485201deba3bc9ffdd44a9 100644 (file)
@@ -276,6 +276,10 @@ END_EXTERN_C()
 
 #define INIT_ZVAL(z) z = zval_used_for_init;
 
+#define ALLOC_INIT_ZVAL(zp)                                            \
+       (zp) = (zval *) emalloc(sizeof(zval));          \
+       INIT_ZVAL(*zp);
+
 #define MAKE_STD_ZVAL(zv)                               \
        zv = (zval *) emalloc(sizeof(zval)); \
        INIT_PZVAL(zv);
@@ -290,10 +294,18 @@ END_EXTERN_C()
                        **(ppzv) = *orig_ptr;                                                   \
                        zval_copy_ctor(*(ppzv));                                                \
                        (*(ppzv))->refcount=1;                                                  \
-                       (*(ppzv))->is_ref = 0;                                          \
+                       (*(ppzv))->is_ref = 0;                                                  \
                }                                                                                                       \
        }
 
+#define COPY_PZVAL_TO_ZVAL(zv, pzv)                    \
+       (zv) = *(pzv);                                                  \
+       if ((pzv)->refcount>1) {                                \
+               zval_copy_ctor(&(zv));                          \
+               (pzv)->refcount--;                                      \
+       }                                                                               \
+       INIT_PZVAL(&(zv));
+
 #define ZEND_MAX_RESERVED_RESOURCES    1
 
 #endif /* _ZEND_H */
index 3c475d0b67aabe04b2d297df52767fa1a0402f61..886da00de8a167123a97ffb92ebac5b24d1a07bd 100644 (file)
@@ -124,8 +124,8 @@ ZEND_API int add_get_assoc_stringl(zval *arg, char *key, char *str, uint length,
 ZEND_API int add_get_index_string(zval *arg, uint idx, char *str, void **dest, int duplicate);
 ZEND_API int add_get_index_stringl(zval *arg, uint idx, char *str, uint length, void **dest, int duplicate);
 
-ZEND_API int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval, int param_count, zval *params[]);
-ZEND_API int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval *retval, int param_count, zval **params[], int no_separation);
+ZEND_API int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, int param_count, zval *params[]);
+ZEND_API int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval **retval_ptr_ptr, int param_count, zval **params[], int no_separation);
 
 ZEND_API int add_property_long(zval *arg, char *key, long l);
 ZEND_API int add_property_resource(zval *arg, char *key, long r);
index 5f16d235800b60e72b3db9d39435ee1c6e0211dd..45410dae02129a6feb14e6482e08ed5c592ef8a8 100644 (file)
@@ -1854,7 +1854,7 @@ void do_include_or_eval(int type, znode *result, znode *op1 CLS_DC)
        zend_op *opline = get_next_op(CG(active_op_array) CLS_CC);
 
        opline->opcode = ZEND_INCLUDE_OR_EVAL;
-       opline->result.op_type = IS_TMP_VAR;
+       opline->result.op_type = IS_VAR;
        opline->result.u.var = get_temporary_variable(CG(active_op_array));
        opline->op1 = *op1;
        SET_UNUSED(opline->op2);
index c20d9fe98b3157b9b043e230ff34a869fccd45a0..1cea3fed486c2813eb7ebe7138a54ef226853f34 100644 (file)
@@ -1473,26 +1473,28 @@ overloaded_function_call_cont:
 do_fcall_common:
                                {
                                        zval **original_return_value;
-                                       int return_value_not_used = (opline->result.u.EA.type & EXT_TYPE_UNUSED);
-
+                                       int return_value_used = !(opline->result.u.EA.type & EXT_TYPE_UNUSED);
 
                                        zend_ptr_stack_push(&EG(argument_stack), (void *) opline->extended_value);
+
                                        Ts[opline->result.u.var].var.ptr_ptr = &Ts[opline->result.u.var].var.ptr;
-                                       /* The emalloc() could be optimized out for call user function but it
-                                          creates a problem with include() */
-                                       Ts[opline->result.u.var].var.ptr = (zval *)emalloc(sizeof(zval));
-                                       INIT_ZVAL(*(Ts[opline->result.u.var].var.ptr));
 
                                        if (function_state.function->type==ZEND_INTERNAL_FUNCTION) {    
-                                               ((zend_internal_function *) function_state.function)->handler(opline->extended_value, Ts[opline->result.u.var].var.ptr, &EG(regular_list), &EG(persistent_list), object.ptr, !return_value_not_used);
+                                               Ts[opline->result.u.var].var.ptr = (zval *)emalloc(sizeof(zval));
+                                               INIT_ZVAL(*(Ts[opline->result.u.var].var.ptr));
+                                               ((zend_internal_function *) function_state.function)->handler(opline->extended_value, Ts[opline->result.u.var].var.ptr, &EG(regular_list), &EG(persistent_list), object.ptr, return_value_used);
                                                if (object.ptr) {
                                                        object.ptr->refcount--;
                                                }
                                                Ts[opline->result.u.var].var.ptr->is_ref = 0;
                                                Ts[opline->result.u.var].var.ptr->refcount = 1;
+                                               if (!return_value_used) {
+                                                       zval_ptr_dtor(&Ts[opline->result.u.var].var.ptr);
+                                               }
                                        } else if (function_state.function->type==ZEND_USER_FUNCTION) {
                                                HashTable *calling_symbol_table;
 
+                                               Ts[opline->result.u.var].var.ptr = NULL;
                                                if (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
                                                        /*printf("Cache hit!  Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/
                                                        function_state.function_symbol_table = *(EG(symtable_cache_ptr)--);
@@ -1518,7 +1520,15 @@ do_fcall_common:
                                                original_return_value = EG(return_value_ptr_ptr);
                                                EG(return_value_ptr_ptr) = Ts[opline->result.u.var].var.ptr_ptr;
                                                EG(active_op_array) = (zend_op_array *) function_state.function;
+
                                                zend_execute(EG(active_op_array) ELS_CC);
+
+                                               if (return_value_used && !Ts[opline->result.u.var].var.ptr) {
+                                                       Ts[opline->result.u.var].var.ptr = (zval *) emalloc(sizeof(zval));
+                                                       INIT_ZVAL(*Ts[opline->result.u.var].var.ptr);
+                                               } else if (!return_value_used && Ts[opline->result.u.var].var.ptr) {
+                                                       zval_ptr_dtor(&Ts[opline->result.u.var].var.ptr);
+                                               }
                                                EG(opline_ptr) = &opline;
                                                EG(active_op_array) = op_array;
                                                EG(return_value_ptr_ptr)=original_return_value;
@@ -1531,11 +1541,13 @@ do_fcall_common:
                                                }
                                                EG(active_symbol_table) = calling_symbol_table;
                                        } else { /* ZEND_OVERLOADED_FUNCTION */
+                                               Ts[opline->result.u.var].var.ptr = (zval *)emalloc(sizeof(zval));
+                                               INIT_ZVAL(*(Ts[opline->result.u.var].var.ptr));
                                                call_overloaded_function(opline->extended_value, Ts[opline->result.u.var].var.ptr, &EG(regular_list), &EG(persistent_list) ELS_CC);
                                                efree(fbc);
-                                       }
-                                       if (return_value_not_used) {
-                                               zval_ptr_dtor(&Ts[opline->result.u.var].var.ptr);
+                                               if (!return_value_used) {
+                                                       zval_ptr_dtor(&Ts[opline->result.u.var].var.ptr);
+                                               }
                                        }
                                        object.ptr = zend_ptr_stack_pop(&EG(arg_types_stack));
                                        if (opline->opcode == ZEND_DO_FCALL_BY_NAME) {
@@ -1561,25 +1573,23 @@ do_fcall_common:
                                                        (*retval_ptr_ptr)->is_ref = 1;
                                                }
                                                (*retval_ptr_ptr)->refcount++;
-                                               efree(*EG(return_value_ptr_ptr));
                                                (*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
                                        } else {
                                                retval_ptr = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R);
                                        
                                                if (!EG(free_op1)) { /* Not a temp var */
                                                        if (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0) {
-                                                               /**(EG(return_value_ptr_ptr)) = (zval *)emalloc(sizeof(zval));*/
+                                                               *(EG(return_value_ptr_ptr)) = (zval *)emalloc(sizeof(zval));
                                                                **EG(return_value_ptr_ptr) = *retval_ptr;
                                                                (*EG(return_value_ptr_ptr))->is_ref = 0;
                                                                (*EG(return_value_ptr_ptr))->refcount = 1;
                                                                zval_copy_ctor(*EG(return_value_ptr_ptr));
                                                        } else {
-                                                               efree(*EG(return_value_ptr_ptr));
                                                                *EG(return_value_ptr_ptr) = retval_ptr;
                                                                retval_ptr->refcount++;
                                                        }
                                                } else {
-                                                       /**(EG(return_value_ptr_ptr))= (zval *)emalloc(sizeof(zval));*/
+                                                       *(EG(return_value_ptr_ptr))= (zval *)emalloc(sizeof(zval));
                                                        **EG(return_value_ptr_ptr) = *retval_ptr;
                                                        (*EG(return_value_ptr_ptr))->refcount = 1;
                                                        (*EG(return_value_ptr_ptr))->is_ref = 0;
@@ -1940,26 +1950,20 @@ send_by_ref:
                                                        break;
                                        }
                                        FREE_OP(&opline->op1, EG(free_op1));
-
+                                       Ts[opline->result.u.var].var.ptr = NULL;
+                                       Ts[opline->result.u.var].var.ptr_ptr = &Ts[opline->result.u.var].var.ptr;
                                        if (new_op_array) {
-                                               zval *return_value_ptr;
-                                               /*Ts[opline->result.u.var].tmp_var.value.lval = 1;
-                                               Ts[opline->result.u.var].tmp_var.type = IS_LONG;
-                                               EG(return_value) = &Ts[opline->result.u.var].tmp_var;
-                                               */
-                                               return_value_ptr = emalloc(sizeof(zval));
-                                               
-                                               INIT_PZVAL(return_value_ptr);
-                                               return_value_ptr->value.lval = 1;
-                                               return_value_ptr->type = IS_LONG;
-                                               EG(return_value_ptr_ptr) = &return_value_ptr;
+                                               EG(return_value_ptr_ptr) = Ts[opline->result.u.var].var.ptr_ptr;
                                                EG(active_op_array) = new_op_array;
 
                                                zend_execute(new_op_array ELS_CC);
 
-                                               Ts[opline->result.u.var].tmp_var = *return_value_ptr;
-                                               zval_copy_ctor(&Ts[opline->result.u.var].tmp_var);
-                                               zval_ptr_dtor(&return_value_ptr);
+                                               if (!Ts[opline->result.u.var].var.ptr) { /* there was no return statement */
+                                                       Ts[opline->result.u.var].var.ptr = (zval *) emalloc(sizeof(zval));
+                                                       INIT_PZVAL(Ts[opline->result.u.var].var.ptr);
+                                                       Ts[opline->result.u.var].var.ptr->value.lval = 1;
+                                                       Ts[opline->result.u.var].var.ptr->type = IS_LONG;
+                                               }
 
                                                EG(opline_ptr) = &opline;
                                                EG(active_op_array) = op_array;
@@ -1967,7 +1971,8 @@ send_by_ref:
                                                destroy_op_array(new_op_array);
                                                efree(new_op_array);
                                        } else {
-                                               INIT_ZVAL(Ts[opline->result.u.var].tmp_var);
+                                               Ts[opline->result.u.var].var.ptr = (zval *) emalloc(sizeof(zval));
+                                               INIT_ZVAL(*Ts[opline->result.u.var].var.ptr);
                                        }
                                        EG(return_value_ptr_ptr) = original_return_value;
                                }
index 4075588703accf943dda61d3f611291ac154cfde..0eb61c077179b45d46918a55528d1634bcd4fd74 100644 (file)
@@ -47,7 +47,7 @@ void shutdown_executor(ELS_D);
 void execute(zend_op_array *op_array ELS_DC);
 ZEND_API int zend_is_true(zval *op);
 ZEND_API inline void safe_free_zval_ptr(zval *p);
-ZEND_API void zend_eval_string(char *str, zval *retval CLS_DC ELS_DC);
+ZEND_API void zend_eval_string(char *str, zval *retval_ptr CLS_DC ELS_DC);
 ZEND_API inline int i_zend_is_true(zval *op);
 ZEND_API int zval_update_constant(zval **pp);
 ZEND_API inline void zend_assign_to_variable_reference(znode *result, zval **variable_ptr_ptr, zval **value_ptr_ptr, temp_variable *Ts ELS_DC);
index 938b11e235046d4e6195fc2589fb6440705db601..6325b57f2d9d01e4959a43675a677c36065db0fb 100644 (file)
@@ -88,19 +88,12 @@ void init_executor(CLS_D ELS_DC)
        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
-#if ZEND_DEBUG
+#if 0&&ZEND_DEBUG
        original_sigsegv_handler = signal(SIGSEGV, zend_handle_sigsegv);
 #endif
-#endif
-       /*
-       EG(return_value) = &EG(global_return_value);
-       var_reset(EG(return_value));
-       */
-       EG(return_value_ptr_ptr) = &EG(global_return_value);
-       EG(global_return_value) = emalloc(sizeof(zval));
-       INIT_PZVAL(EG(global_return_value));
-       var_reset(EG(global_return_value));
+       EG(return_value_ptr_ptr) = &EG(global_return_value_ptr);
+       EG(global_return_value_ptr) = &EG(global_return_value);
+       INIT_ZVAL(EG(global_return_value));
 
        EG(symtable_cache_ptr) = EG(symtable_cache)-1;
        EG(symtable_cache_limit)=EG(symtable_cache)+SYMTABLE_CACHE_SIZE-1;
@@ -126,8 +119,7 @@ void init_executor(CLS_D ELS_DC)
 
 void shutdown_executor(ELS_D)
 {
-       zval_ptr_dtor(&EG(global_return_value));
-       /*zval_dtor(&EG(global_return_value));*/
+       zval_dtor(&EG(global_return_value));
        zend_ptr_stack_destroy(&EG(arg_types_stack));
        zend_stack_destroy(&EG(overloaded_objects_stack));
                        
@@ -295,25 +287,31 @@ ZEND_API int zval_update_constant(zval **pp)
 }
 
 
-int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval, int param_count, zval *params[])
+int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, int param_count, zval *params[])
 {
        zval ***params_array = (zval ***) emalloc(sizeof(zval **)*param_count);
        int i;
        int ex_retval;
+       zval *local_retval_ptr;
 
        for (i=0; i<param_count; i++) {
                params_array[i] = &params[i];
        }
-       ex_retval = call_user_function_ex(function_table, object, function_name, retval, param_count, params_array, 1);
+       ex_retval = call_user_function_ex(function_table, object, function_name, &local_retval_ptr, param_count, params_array, 1);
+       if (local_retval_ptr) {
+               COPY_PZVAL_TO_ZVAL(*retval_ptr, local_retval_ptr);
+       } else {
+               INIT_ZVAL(*retval_ptr);
+       }
        efree(params_array);
        return ex_retval;
 }
 
 
-int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval *retval, int param_count, zval **params[], int no_separation)
+int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval **retval_ptr_ptr, int param_count, zval **params[], int no_separation)
 {
        int i;
-       zval *original_return_value;
+       zval **original_return_value;
        HashTable *calling_symbol_table;
        zend_function_state function_state;
        zend_function_state *original_function_state_ptr;
@@ -369,7 +367,7 @@ int call_user_function_ex(HashTable *function_table, zval *object, zval *functio
 
        zend_ptr_stack_push(&EG(argument_stack), (void *) (long) param_count);
 
-       var_uninit(retval);
+       *retval_ptr_ptr = NULL;
        if (function_state.function->type == ZEND_USER_FUNCTION) {
                calling_symbol_table = EG(active_symbol_table);
                EG(active_symbol_table) = (HashTable *) emalloc(sizeof(HashTable));
@@ -382,20 +380,22 @@ int call_user_function_ex(HashTable *function_table, zval *object, zval *functio
                        zend_hash_update_ptr(EG(active_symbol_table), "this", sizeof("this"), dummy, sizeof(zval *), (void **) &this_ptr);
                        zend_assign_to_variable_reference(NULL, this_ptr, &object, NULL ELS_CC);
                }
-               original_return_value = EG(return_value);
+               original_return_value = EG(return_value_ptr_ptr);
                original_op_array = EG(active_op_array);
-               EG(return_value) = retval;
+               EG(return_value_ptr_ptr) = retval_ptr_ptr;
                EG(active_op_array) = (zend_op_array *) function_state.function;
-               original_opline_ptr = EG(opline_ptr);   
+               original_opline_ptr = EG(opline_ptr);
                zend_execute(EG(active_op_array) ELS_CC);
                zend_hash_destroy(EG(active_symbol_table));             
                efree(EG(active_symbol_table));
                EG(active_symbol_table) = calling_symbol_table;
                EG(active_op_array) = original_op_array;
-               EG(return_value)=original_return_value;
+               EG(return_value_ptr_ptr)=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), object, 1);
+               ALLOC_INIT_ZVAL(*retval_ptr_ptr);
+               ((zend_internal_function *) function_state.function)->handler(param_count, *retval_ptr_ptr, &EG(regular_list), &EG(persistent_list), object, 1);
+               INIT_PZVAL(*retval_ptr_ptr);
        }
        zend_ptr_stack_clear_multiple(ELS_C);
        EG(function_state_ptr) = original_function_state_ptr;
@@ -404,7 +404,7 @@ int call_user_function_ex(HashTable *function_table, zval *object, zval *functio
 }
 
 
-ZEND_API void zend_eval_string(char *str, zval *retval CLS_DC ELS_DC)
+ZEND_API void zend_eval_string(char *str, zval *retval_ptr CLS_DC ELS_DC)
 {
        zval pv;
        zend_op_array *new_op_array;
@@ -412,7 +412,7 @@ ZEND_API void zend_eval_string(char *str, zval *retval CLS_DC ELS_DC)
        zend_function_state *original_function_state_ptr = EG(function_state_ptr);
        int original_handle_op_arrays;
 
-       if (retval) {
+       if (retval_ptr) {
                pv.value.str.len = strlen(str)+sizeof("return  ;")-1;
                pv.value.str.val = emalloc(pv.value.str.len+1);
                strcpy(pv.value.str.val, "return ");
@@ -432,25 +432,35 @@ ZEND_API void zend_eval_string(char *str, zval *retval CLS_DC ELS_DC)
        CG(handle_op_arrays) = original_handle_op_arrays;
 
        if (new_op_array) {
-               zval dummy_retval;
-               zval *original_return_value = EG(return_value);
+               zval *local_retval_ptr=NULL;
+               zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
                zend_op **original_opline_ptr = EG(opline_ptr);
                
-               EG(return_value) = (retval?retval:&dummy_retval);
-               var_reset(EG(return_value));
+               EG(return_value_ptr_ptr) = &local_retval_ptr;
                EG(active_op_array) = new_op_array;
                EG(no_extensions)=1;
+
                zend_execute(new_op_array ELS_CC);
+
+               if (local_retval_ptr) {
+                       if (retval_ptr) {
+                               COPY_PZVAL_TO_ZVAL(*retval_ptr, local_retval_ptr);
+                       } else {
+                               zval_ptr_dtor(&local_retval_ptr);
+                       }
+               } else {
+                       if (retval_ptr) {
+                               INIT_ZVAL(*retval_ptr);
+                       }
+               }
+
                EG(no_extensions)=0;
                EG(opline_ptr) = original_opline_ptr;
                EG(active_op_array) = original_active_op_array;
                EG(function_state_ptr) = original_function_state_ptr;
                destroy_op_array(new_op_array);
                efree(new_op_array);
-               EG(return_value) = original_return_value;
-               if (!retval) {
-                       zval_dtor(&dummy_retval);
-               }
+               EG(return_value_ptr_ptr) = original_return_value_ptr_ptr;
        } else {
                printf("Failed executing:\n%s\n", str);
        }
index 2cd100960317b6916cd1d73062be37a7e090ebf3..c2e61115ddac1f4f2cd8f1275176bcd46bd3a646 100644 (file)
@@ -110,7 +110,6 @@ struct _zend_compiler_globals {
 
 
 struct _zend_executor_globals {
-       zval *return_value;
        zval **return_value_ptr_ptr;
 
        zval uninitialized_zval;
@@ -122,7 +121,10 @@ struct _zend_executor_globals {
        zend_function_state *function_state_ptr;
        zend_ptr_stack arg_types_stack;
        zend_stack overloaded_objects_stack;
-       zval *global_return_value;
+
+       /* for global return() support */
+       zval *global_return_value_ptr;
+       zval global_return_value;
 
        /* symbol table cache */
        HashTable *symtable_cache[SYMTABLE_CACHE_SIZE];