]> granicus.if.org Git - php/commitdiff
Optimized function call helper
authorDmitry Stogov <dmitry@php.net>
Mon, 21 Apr 2008 10:14:20 +0000 (10:14 +0000)
committerDmitry Stogov <dmitry@php.net>
Mon, 21 Apr 2008 10:14:20 +0000 (10:14 +0000)
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 839829a97721a46080da3f927f6d24ff65f3e8d4..010083826f67f3fbbc70a12aa28d4d57b17777c9 100644 (file)
@@ -2122,10 +2122,9 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
        zend_ptr_stack_3_pop(&EG(arg_types_stack), (void*)&EX(called_scope), (void**)&ex_object, (void**)&EX(fbc));
        EX(function_state).arguments = zend_vm_stack_push_args(opline->extended_value TSRMLS_CC);
 
-       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
-
        if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
                ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
+               EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
                EX_T(opline->result.u.var).var.fcall_returned_reference = EX(function_state).function->common.return_reference;
 
                if (EX(function_state).function->common.arg_info) {
@@ -2145,20 +2144,12 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
                        zend_execute_internal(EXECUTE_DATA, RETURN_VALUE_USED(opline) TSRMLS_CC);
                }
 
-/*     We shouldn't fix bad extensions here,
-    because it can break proper ones (Bug #34045)
-               if (!EX(function_state).function->common.return_reference) {
-                       Z_UNSET_ISREF_P(EX_T(opline->result.u.var).var.ptr);
-                       Z_SET_REFCOUNT_P(EX_T(opline->result.u.var).var.ptr, 1);
-               }
-*/
                if (!RETURN_VALUE_USED(opline)) {
                        zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
                }
        } else if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
                zval **original_return_value = EG(return_value_ptr_ptr);
 
-               EX_T(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]);*/
                        EG(active_symbol_table) = *(EG(symtable_cache_ptr)--);
@@ -2167,18 +2158,18 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
                        zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0);
                        /*printf("Cache miss!  Initialized %x\n", EG(active_symbol_table));*/
                }
-               EG(return_value_ptr_ptr) = RETURN_VALUE_USED(opline) ? &EX_T(opline->result.u.var).var.ptr : NULL;
-               EG(active_op_array) = (zend_op_array *) EX(function_state).function;
 
-               zend_execute(EG(active_op_array) TSRMLS_CC);
-               EX_T(opline->result.u.var).var.fcall_returned_reference = EG(active_op_array)->return_reference;
-
-               if (RETURN_VALUE_USED(opline)) {
-                       if (!EX_T(opline->result.u.var).var.ptr && !EG(exception)) {
-                               ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
-                       }
+               EG(active_op_array) = &EX(function_state).function->op_array;
+               EG(return_value_ptr_ptr) = NULL;
+               if (RETURN_VALUE_USED(opline)) {                        
+                       EG(return_value_ptr_ptr) = &EX_T(opline->result.u.var).var.ptr;
+                       EX_T(opline->result.u.var).var.ptr = NULL;
+                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                       EX_T(opline->result.u.var).var.fcall_returned_reference = EX(function_state).function->common.return_reference;
                }
 
+               zend_execute(EG(active_op_array) TSRMLS_CC);
+
                EG(opline_ptr) = &EX(opline);
                EG(active_op_array) = EX(op_array);
                EG(return_value_ptr_ptr)=original_return_value;
@@ -2213,35 +2204,33 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
                        Z_UNSET_ISREF_P(EX_T(opline->result.u.var).var.ptr);
                        Z_SET_REFCOUNT_P(EX_T(opline->result.u.var).var.ptr, 1);
                        EX_T(opline->result.u.var).var.fcall_returned_reference = 0;
+                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
                }
        }
 
        EX(function_state).function = (zend_function *) EX(op_array);
        EX(function_state).arguments = NULL;
 
-       if (EG(This)) {
-               if (EG(exception) && IS_CTOR_CALL(EX(called_scope))) {
-                       if (IS_CTOR_USED(EX(called_scope))) {
-                               Z_DELREF_P(EG(This));
-                       }
-                       if (Z_REFCOUNT_P(EG(This)) == 1) {
-                               zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
+       if (should_change_scope) {
+               if (EG(This)) {
+                       if (EG(exception) && IS_CTOR_CALL(EX(called_scope))) {
+                               if (IS_CTOR_USED(EX(called_scope))) {
+                                       Z_DELREF_P(EG(This));
+                               }
+                               if (Z_REFCOUNT_P(EG(This)) == 1) {
+                                       zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
+                               }
                        }
-               }
-               if (should_change_scope) {
                        zval_ptr_dtor(&EG(This));
                }
-       }
-
-       EX(object) = ex_object;
-       EX(called_scope) = DECODE_CTOR(EX(called_scope));
-
-       if (should_change_scope) {
                EG(This) = current_this;
                EG(scope) = current_scope;
                EG(called_scope) = current_called_scope;
        }
 
+       EX(object) = ex_object;
+       EX(called_scope) = DECODE_CTOR(EX(called_scope));
+
        zend_vm_stack_clear_multiple(TSRMLS_C);
 
        if (EG(exception)) {
index 69688177d70c02bbf462f6b24053f0df753e5adc..9d1c30ee4ba78657cafd4c6b875d4b6584f4713e 100644 (file)
@@ -169,10 +169,9 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
        zend_ptr_stack_3_pop(&EG(arg_types_stack), (void*)&EX(called_scope), (void**)&ex_object, (void**)&EX(fbc));
        EX(function_state).arguments = zend_vm_stack_push_args(opline->extended_value TSRMLS_CC);
 
-       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
-
        if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
                ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
+               EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
                EX_T(opline->result.u.var).var.fcall_returned_reference = EX(function_state).function->common.return_reference;
 
                if (EX(function_state).function->common.arg_info) {
@@ -192,20 +191,12 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
                        zend_execute_internal(execute_data, RETURN_VALUE_USED(opline) TSRMLS_CC);
                }
 
-/*     We shouldn't fix bad extensions here,
-    because it can break proper ones (Bug #34045)
-               if (!EX(function_state).function->common.return_reference) {
-                       Z_UNSET_ISREF_P(EX_T(opline->result.u.var).var.ptr);
-                       Z_SET_REFCOUNT_P(EX_T(opline->result.u.var).var.ptr, 1);
-               }
-*/
                if (!RETURN_VALUE_USED(opline)) {
                        zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
                }
        } else if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
                zval **original_return_value = EG(return_value_ptr_ptr);
 
-               EX_T(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]);*/
                        EG(active_symbol_table) = *(EG(symtable_cache_ptr)--);
@@ -214,18 +205,18 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
                        zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0);
                        /*printf("Cache miss!  Initialized %x\n", EG(active_symbol_table));*/
                }
-               EG(return_value_ptr_ptr) = RETURN_VALUE_USED(opline) ? &EX_T(opline->result.u.var).var.ptr : NULL;
-               EG(active_op_array) = (zend_op_array *) EX(function_state).function;
-
-               zend_execute(EG(active_op_array) TSRMLS_CC);
-               EX_T(opline->result.u.var).var.fcall_returned_reference = EG(active_op_array)->return_reference;
 
+               EG(active_op_array) = &EX(function_state).function->op_array;
+               EG(return_value_ptr_ptr) = NULL;
                if (RETURN_VALUE_USED(opline)) {
-                       if (!EX_T(opline->result.u.var).var.ptr && !EG(exception)) {
-                               ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
-                       }
+                       EG(return_value_ptr_ptr) = &EX_T(opline->result.u.var).var.ptr;
+                       EX_T(opline->result.u.var).var.ptr = NULL;
+                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                       EX_T(opline->result.u.var).var.fcall_returned_reference = EX(function_state).function->common.return_reference;
                }
 
+               zend_execute(EG(active_op_array) TSRMLS_CC);
+
                EG(opline_ptr) = &EX(opline);
                EG(active_op_array) = EX(op_array);
                EG(return_value_ptr_ptr)=original_return_value;
@@ -260,35 +251,33 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
                        Z_UNSET_ISREF_P(EX_T(opline->result.u.var).var.ptr);
                        Z_SET_REFCOUNT_P(EX_T(opline->result.u.var).var.ptr, 1);
                        EX_T(opline->result.u.var).var.fcall_returned_reference = 0;
+                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
                }
        }
 
        EX(function_state).function = (zend_function *) EX(op_array);
        EX(function_state).arguments = NULL;
 
-       if (EG(This)) {
-               if (EG(exception) && IS_CTOR_CALL(EX(called_scope))) {
-                       if (IS_CTOR_USED(EX(called_scope))) {
-                               Z_DELREF_P(EG(This));
-                       }
-                       if (Z_REFCOUNT_P(EG(This)) == 1) {
-                               zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
+       if (should_change_scope) {
+               if (EG(This)) {
+                       if (EG(exception) && IS_CTOR_CALL(EX(called_scope))) {
+                               if (IS_CTOR_USED(EX(called_scope))) {
+                                       Z_DELREF_P(EG(This));
+                               }
+                               if (Z_REFCOUNT_P(EG(This)) == 1) {
+                                       zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
+                               }
                        }
-               }
-               if (should_change_scope) {
                        zval_ptr_dtor(&EG(This));
                }
-       }
-
-       EX(object) = ex_object;
-       EX(called_scope) = DECODE_CTOR(EX(called_scope));
-
-       if (should_change_scope) {
                EG(This) = current_this;
                EG(scope) = current_scope;
                EG(called_scope) = current_called_scope;
        }
 
+       EX(object) = ex_object;
+       EX(called_scope) = DECODE_CTOR(EX(called_scope));
+
        zend_vm_stack_clear_multiple(TSRMLS_C);
 
        if (EG(exception)) {