]> granicus.if.org Git - php/commitdiff
Added specialized versions of DO_FCALL handler:
authorDmitry Stogov <dmitry@zend.com>
Wed, 25 Feb 2015 07:37:21 +0000 (10:37 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 25 Feb 2015 07:37:21 +0000 (10:37 +0300)
  DO_ICALL - for internal functions
  DO_UCALL - for user functions
  DO_FCALL_BY_NAME - plain, most probably user, funcstions (not methods)

14 files changed:
Zend/zend_builtin_functions.c
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c
Zend/zend_execute_API.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_opcodes.c
Zend/zend_vm_opcodes.h
ext/opcache/Optimizer/block_pass.c
ext/opcache/Optimizer/optimize_func_calls.c
ext/opcache/Optimizer/pass1_5.c
ext/opcache/ZendAccelerator.c
sapi/phpdbg/phpdbg_prompt.c

index 035a4c6c88604d6ddecd02553f0870a60c2a911e..195d9c2509f59c06c9dbf40c2898e2e33f1c9a37 100644 (file)
@@ -2258,6 +2258,9 @@ ZEND_FUNCTION(debug_print_backtrace)
                    skip->prev_execute_data->func &&
                    ZEND_USER_CODE(skip->prev_execute_data->func->common.type) &&
                    skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
+                   skip->prev_execute_data->opline->opcode != ZEND_DO_ICALL &&
+                   skip->prev_execute_data->opline->opcode != ZEND_DO_UCALL &&
+                   skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
                    skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
                        skip = skip->prev_execute_data;
                }
@@ -2453,6 +2456,9 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
                    skip->prev_execute_data->func &&
                    ZEND_USER_CODE(skip->prev_execute_data->func->common.type) &&
                    skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
+                   skip->prev_execute_data->opline->opcode != ZEND_DO_ICALL &&
+                   skip->prev_execute_data->opline->opcode != ZEND_DO_UCALL &&
+                   skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
                    skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
                        skip = skip->prev_execute_data;
                }
index 9fbfa1f82f8edd801d3531210324b6228487f825..1a716080838e7a935372f41755b91e4ccf24bd05 100644 (file)
@@ -2617,6 +2617,31 @@ uint32_t zend_compile_args(zend_ast *ast, zend_function *fbc) /* {{{ */
 }
 /* }}} */
 
+ZEND_API zend_uchar zend_get_call_op(zend_uchar init_op, zend_function *fbc) /* {{{ */
+{
+       if (fbc) {
+               if (fbc->type == ZEND_INTERNAL_FUNCTION) {
+                       if (!zend_execute_internal &&
+                           !fbc->common.scope &&
+                           !(fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED|ZEND_ACC_HAS_TYPE_HINTS))) {
+                               return ZEND_DO_ICALL;
+                       }
+               } else {
+                       if (zend_execute_ex == execute_ex &&
+                           !(fbc->common.fn_flags & ZEND_ACC_GENERATOR)) {
+                               return ZEND_DO_UCALL;
+                       }
+               }
+       } else if (zend_execute_ex == execute_ex &&
+                  !zend_execute_internal &&
+                  (init_op == ZEND_INIT_FCALL_BY_NAME ||
+                   init_op == ZEND_INIT_NS_FCALL_BY_NAME)) {
+               return ZEND_DO_FCALL_BY_NAME;
+       }
+       return ZEND_DO_FCALL;
+}
+/* }}} */
+
 void zend_compile_call_common(znode *result, zend_ast *args_ast, zend_function *fbc) /* {{{ */
 {
        zend_op *opline;
@@ -2636,7 +2661,7 @@ void zend_compile_call_common(znode *result, zend_ast *args_ast, zend_function *
        }
 
        call_flags = (opline->opcode == ZEND_NEW ? ZEND_CALL_CTOR : 0);
-       opline = zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL);
+       opline = zend_emit_op(result, zend_get_call_op(opline->opcode, fbc), NULL, NULL);
        opline->op1.num = call_flags;
 
        zend_do_extended_fcall_end();
index 6073e240f329a03148654fba2c10b4bcb3dc9de4..8e4148795e8437f6e998f1ea7970bab5101404c9 100644 (file)
@@ -718,6 +718,7 @@ ZEND_API zend_bool zend_is_compiling(void);
 ZEND_API char *zend_make_compiled_string_description(const char *name);
 ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers);
 uint32_t zend_get_class_fetch_type(zend_string *name);
+ZEND_API zend_uchar zend_get_call_op(zend_uchar init_op, zend_function *fbc);
 
 typedef zend_bool (*zend_auto_global_callback)(zend_string *name);
 typedef struct _zend_auto_global {
index b016df1e25242b9fa5bbf9cae6d003b19c1c27d3..0cf2f2c53eba901e0c564a5f33e0d6e61f57b307 100644 (file)
@@ -1742,7 +1742,7 @@ void zend_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */
  *                             +----------------------------------------+
  */
 
-static zend_always_inline void i_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
+static zend_always_inline void i_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value, int check_this) /* {{{ */
 {
        uint32_t first_extra_arg, num_args;
        ZEND_ASSERT(EX(func) == (zend_function*)op_array);
@@ -1798,7 +1798,7 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu
                } while (var != end);
        }
 
-       if (op_array->this_var != (uint32_t)-1 && EXPECTED(Z_OBJ(EX(This)))) {
+       if (check_this && op_array->this_var != (uint32_t)-1 && EXPECTED(Z_OBJ(EX(This)))) {
                ZVAL_OBJ(EX_VAR(op_array->this_var), Z_OBJ(EX(This)));
                GC_REFCOUNT(Z_OBJ(EX(This)))++;
        }
@@ -1966,7 +1966,7 @@ ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_execute_data
 
        EX(symbol_table) = NULL;
 
-       i_init_func_execute_data(execute_data, op_array, return_value);
+       i_init_func_execute_data(execute_data, op_array, return_value, 1);
 
        return execute_data;
 }
index fc94beeb7fc5b284c0a209bb7709e498d0d6441a..f52d9f33ce4d2e57086d54631cb243c5bae0eb36 100644 (file)
@@ -691,7 +691,10 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /
                EG(current_execute_data) = &dummy_execute_data;
        } else if (EG(current_execute_data)->func &&
                   ZEND_USER_CODE(EG(current_execute_data)->func->common.type) &&
-                  EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL) {
+                  EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL &&
+                  EG(current_execute_data)->opline->opcode != ZEND_DO_ICALL &&
+                  EG(current_execute_data)->opline->opcode != ZEND_DO_UCALL &&
+                  EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL_BY_NAME) {
                /* Insert fake frame in case of include or magic calls */
                dummy_execute_data = *EG(current_execute_data);
                dummy_execute_data.prev_execute_data = EG(current_execute_data);
index 8e2051e6c0aa82d3a89c3f02124722c91dec7fa9..04b1d1d6962585d0845023764d00b15892a9d187 100644 (file)
@@ -2354,7 +2354,10 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMPVAR|UNUSED|CV, CONST|TMPVAR|CV)
                                        opline->opcode == ZEND_NEW
                                ) {
                                        nesting++;
-                               } else if (opline->opcode == ZEND_DO_FCALL) {
+                               } else if (opline->opcode == ZEND_DO_FCALL ||
+                                          opline->opcode == ZEND_DO_ICALL ||
+                                          opline->opcode == ZEND_DO_UCALL ||
+                                          opline->opcode == ZEND_DO_FCALL_BY_NAME) {
                                        nesting--;
                                }
                        } while (nesting);
@@ -2796,6 +2799,185 @@ ZEND_VM_HANDLER(61, ZEND_INIT_FCALL, ANY, CONST)
        ZEND_VM_NEXT_OPCODE();
 }
 
+ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY)
+{
+       USE_OPLINE
+       zend_execute_data *call = EX(call);
+       zend_function *fbc = call->func;
+       zval *ret;
+
+       SAVE_OPLINE();
+       EX(call) = call->prev_execute_data;
+
+       LOAD_OPLINE();
+
+       call->called_scope = EX(called_scope);
+       Z_OBJ(call->This) = Z_OBJ(EX(This));
+
+       call->prev_execute_data = execute_data;
+       EG(current_execute_data) = call;
+
+       ret = EX_VAR(opline->result.var);
+       ZVAL_NULL(ret);
+       Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
+
+       fbc->internal_function.handler(call, ret);
+
+       ZEND_ASSERT(
+               !call->func ||
+               !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
+               zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
+
+       EG(current_execute_data) = call->prev_execute_data;
+       zend_vm_stack_free_args(call);
+       zend_vm_stack_free_call_frame(call);
+
+       if (!RETURN_VALUE_USED(opline)) {
+               zval_ptr_dtor(EX_VAR(opline->result.var));
+       }
+
+       if (UNEXPECTED(EG(exception) != NULL)) {
+               zend_throw_exception_internal(NULL);
+               if (RETURN_VALUE_USED(opline)) {
+                       zval_ptr_dtor(EX_VAR(opline->result.var));
+               }
+               HANDLE_EXCEPTION();
+       }
+
+       ZEND_VM_NEXT_OPCODE();
+}
+
+ZEND_VM_HANDLER(130, ZEND_DO_UCALL, ANY, ANY)
+{
+       USE_OPLINE
+       zend_execute_data *call = EX(call);
+       zend_function *fbc = call->func;
+       zval *ret;
+
+       SAVE_OPLINE();
+       EX(call) = call->prev_execute_data;
+
+       LOAD_OPLINE();
+
+       EG(scope) = NULL;
+       ret = NULL;
+       call->symbol_table = NULL;
+       if (RETURN_VALUE_USED(opline)) {
+               ret = EX_VAR(opline->result.var);
+               ZVAL_NULL(ret);
+               Z_VAR_FLAGS_P(ret) = 0;
+       }
+
+       call->prev_execute_data = execute_data;
+       i_init_func_execute_data(call, &fbc->op_array, ret, 0);
+
+       ZEND_VM_ENTER();
+}
+
+ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY)
+{
+       USE_OPLINE
+       zend_execute_data *call = EX(call);
+       zend_function *fbc = call->func;
+       zval *ret;
+
+       SAVE_OPLINE();
+       EX(call) = call->prev_execute_data;
+
+       LOAD_OPLINE();
+
+       if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
+               EG(scope) = NULL;
+               if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+                       if (RETURN_VALUE_USED(opline)) {
+                               zend_generator_create_zval(call, &fbc->op_array, EX_VAR(opline->result.var));
+                       } else {
+                               zend_vm_stack_free_args(call);
+                       }
+
+                       zend_vm_stack_free_call_frame(call);
+               } else {
+                       ret = NULL;
+                       call->symbol_table = NULL;
+                       if (RETURN_VALUE_USED(opline)) {
+                               ret = EX_VAR(opline->result.var);
+                               ZVAL_NULL(ret);
+                               Z_VAR_FLAGS_P(ret) = 0;
+                       }
+
+                       call->prev_execute_data = execute_data;
+                       i_init_func_execute_data(call, &fbc->op_array, ret, 0);
+
+                       ZEND_VM_ENTER();
+               }
+               EG(scope) = EX(func)->op_array.scope;
+       } else {
+               ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
+
+               if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
+                       zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
+                               fbc->common.scope ? fbc->common.scope->name->val : "",
+                               fbc->common.scope ? "::" : "",
+                               fbc->common.function_name->val);
+                       if (UNEXPECTED(EG(exception) != NULL)) {
+                               HANDLE_EXCEPTION();
+                       }
+               }
+
+               call->called_scope = EX(called_scope);
+               Z_OBJ(call->This) = Z_OBJ(EX(This));
+
+               call->prev_execute_data = execute_data;
+               EG(current_execute_data) = call;
+
+               if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
+                       uint32_t i;
+                       uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
+                       zval *p = ZEND_CALL_ARG(call, 1);
+
+                       for (i = 0; i < num_args; ++i) {
+                               zend_verify_internal_arg_type(fbc, i + 1, p);
+                               p++;
+                       }
+                       if (UNEXPECTED(EG(exception) != NULL)) {
+                               EG(current_execute_data) = call->prev_execute_data;
+                               zend_vm_stack_free_args(call);
+                               zend_vm_stack_free_call_frame(call);
+                               zend_throw_exception_internal(NULL);
+                               HANDLE_EXCEPTION();
+                       }
+               }
+
+               ret = EX_VAR(opline->result.var);
+               ZVAL_NULL(ret);
+               Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
+
+               fbc->internal_function.handler(call, ret);
+
+               ZEND_ASSERT(
+                       !call->func ||
+                       !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
+                       zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
+
+               EG(current_execute_data) = call->prev_execute_data;
+               zend_vm_stack_free_args(call);
+               zend_vm_stack_free_call_frame(call);
+
+               if (!RETURN_VALUE_USED(opline)) {
+                       zval_ptr_dtor(EX_VAR(opline->result.var));
+               }
+       }
+
+       if (UNEXPECTED(EG(exception) != NULL)) {
+               zend_throw_exception_internal(NULL);
+               if (RETURN_VALUE_USED(opline)) {
+                       zval_ptr_dtor(EX_VAR(opline->result.var));
+               }
+               HANDLE_EXCEPTION();
+       }
+       ZEND_VM_NEXT_OPCODE();
+}
+
 ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
 {
        USE_OPLINE
@@ -2843,7 +3025,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
                        }
 
                        call->prev_execute_data = execute_data;
-                       i_init_func_execute_data(call, &fbc->op_array, ret);
+                       i_init_func_execute_data(call, &fbc->op_array, ret, 1);
 
                        if (EXPECTED(zend_execute_ex == execute_ex)) {
                                ZEND_VM_ENTER();
@@ -2854,7 +3036,6 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
                }
        } else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) {
                int should_change_scope = 0;
-               zval *ret;
 
                if (fbc->common.scope) {
                        should_change_scope = 1;
@@ -5965,6 +6146,9 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
                        do {
                                switch (opline->opcode) {
                                        case ZEND_DO_FCALL:
+                                       case ZEND_DO_ICALL:
+                                       case ZEND_DO_UCALL:
+                                       case ZEND_DO_FCALL_BY_NAME:
                                                level++;
                                                break;
                                        case ZEND_INIT_FCALL:
@@ -6011,6 +6195,9 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
                                do {
                                        switch (opline->opcode) {
                                                case ZEND_DO_FCALL:
+                                               case ZEND_DO_ICALL:
+                                               case ZEND_DO_UCALL:
+                                               case ZEND_DO_FCALL_BY_NAME:
                                                        level++;
                                                        break;
                                                case ZEND_INIT_FCALL:
index 04a8787262dff64651396bea174d8c18339ed5ed..d4e29353fc118d811a162740d2875b2012235d52 100644 (file)
@@ -486,6 +486,185 @@ static int ZEND_FASTCALL  ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        ZEND_VM_CONTINUE();
 }
 
+static int ZEND_FASTCALL  ZEND_DO_ICALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_execute_data *call = EX(call);
+       zend_function *fbc = call->func;
+       zval *ret;
+
+       SAVE_OPLINE();
+       EX(call) = call->prev_execute_data;
+
+       LOAD_OPLINE();
+
+       call->called_scope = EX(called_scope);
+       Z_OBJ(call->This) = Z_OBJ(EX(This));
+
+       call->prev_execute_data = execute_data;
+       EG(current_execute_data) = call;
+
+       ret = EX_VAR(opline->result.var);
+       ZVAL_NULL(ret);
+       Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
+
+       fbc->internal_function.handler(call, ret);
+
+       ZEND_ASSERT(
+               !call->func ||
+               !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
+               zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
+
+       EG(current_execute_data) = call->prev_execute_data;
+       zend_vm_stack_free_args(call);
+       zend_vm_stack_free_call_frame(call);
+
+       if (!RETURN_VALUE_USED(opline)) {
+               zval_ptr_dtor(EX_VAR(opline->result.var));
+       }
+
+       if (UNEXPECTED(EG(exception) != NULL)) {
+               zend_throw_exception_internal(NULL);
+               if (RETURN_VALUE_USED(opline)) {
+                       zval_ptr_dtor(EX_VAR(opline->result.var));
+               }
+               HANDLE_EXCEPTION();
+       }
+
+       ZEND_VM_NEXT_OPCODE();
+}
+
+static int ZEND_FASTCALL  ZEND_DO_UCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_execute_data *call = EX(call);
+       zend_function *fbc = call->func;
+       zval *ret;
+
+       SAVE_OPLINE();
+       EX(call) = call->prev_execute_data;
+
+       LOAD_OPLINE();
+
+       EG(scope) = NULL;
+       ret = NULL;
+       call->symbol_table = NULL;
+       if (RETURN_VALUE_USED(opline)) {
+               ret = EX_VAR(opline->result.var);
+               ZVAL_NULL(ret);
+               Z_VAR_FLAGS_P(ret) = 0;
+       }
+
+       call->prev_execute_data = execute_data;
+       i_init_func_execute_data(call, &fbc->op_array, ret, 0);
+
+       ZEND_VM_ENTER();
+}
+
+static int ZEND_FASTCALL  ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_execute_data *call = EX(call);
+       zend_function *fbc = call->func;
+       zval *ret;
+
+       SAVE_OPLINE();
+       EX(call) = call->prev_execute_data;
+
+       LOAD_OPLINE();
+
+       if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
+               EG(scope) = NULL;
+               if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+                       if (RETURN_VALUE_USED(opline)) {
+                               zend_generator_create_zval(call, &fbc->op_array, EX_VAR(opline->result.var));
+                       } else {
+                               zend_vm_stack_free_args(call);
+                       }
+
+                       zend_vm_stack_free_call_frame(call);
+               } else {
+                       ret = NULL;
+                       call->symbol_table = NULL;
+                       if (RETURN_VALUE_USED(opline)) {
+                               ret = EX_VAR(opline->result.var);
+                               ZVAL_NULL(ret);
+                               Z_VAR_FLAGS_P(ret) = 0;
+                       }
+
+                       call->prev_execute_data = execute_data;
+                       i_init_func_execute_data(call, &fbc->op_array, ret, 0);
+
+                       ZEND_VM_ENTER();
+               }
+               EG(scope) = EX(func)->op_array.scope;
+       } else {
+               ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
+
+               if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
+                       zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
+                               fbc->common.scope ? fbc->common.scope->name->val : "",
+                               fbc->common.scope ? "::" : "",
+                               fbc->common.function_name->val);
+                       if (UNEXPECTED(EG(exception) != NULL)) {
+                               HANDLE_EXCEPTION();
+                       }
+               }
+
+               call->called_scope = EX(called_scope);
+               Z_OBJ(call->This) = Z_OBJ(EX(This));
+
+               call->prev_execute_data = execute_data;
+               EG(current_execute_data) = call;
+
+               if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
+                       uint32_t i;
+                       uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
+                       zval *p = ZEND_CALL_ARG(call, 1);
+
+                       for (i = 0; i < num_args; ++i) {
+                               zend_verify_internal_arg_type(fbc, i + 1, p);
+                               p++;
+                       }
+                       if (UNEXPECTED(EG(exception) != NULL)) {
+                               EG(current_execute_data) = call->prev_execute_data;
+                               zend_vm_stack_free_args(call);
+                               zend_vm_stack_free_call_frame(call);
+                               zend_throw_exception_internal(NULL);
+                               HANDLE_EXCEPTION();
+                       }
+               }
+
+               ret = EX_VAR(opline->result.var);
+               ZVAL_NULL(ret);
+               Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
+
+               fbc->internal_function.handler(call, ret);
+
+               ZEND_ASSERT(
+                       !call->func ||
+                       !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
+                       zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
+
+               EG(current_execute_data) = call->prev_execute_data;
+               zend_vm_stack_free_args(call);
+               zend_vm_stack_free_call_frame(call);
+
+               if (!RETURN_VALUE_USED(opline)) {
+                       zval_ptr_dtor(EX_VAR(opline->result.var));
+               }
+       }
+
+       if (UNEXPECTED(EG(exception) != NULL)) {
+               zend_throw_exception_internal(NULL);
+               if (RETURN_VALUE_USED(opline)) {
+                       zval_ptr_dtor(EX_VAR(opline->result.var));
+               }
+               HANDLE_EXCEPTION();
+       }
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_FASTCALL  ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -533,7 +712,7 @@ static int ZEND_FASTCALL  ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        }
 
                        call->prev_execute_data = execute_data;
-                       i_init_func_execute_data(call, &fbc->op_array, ret);
+                       i_init_func_execute_data(call, &fbc->op_array, ret, 1);
 
                        if (EXPECTED(zend_execute_ex == execute_ex)) {
                                ZEND_VM_ENTER();
@@ -544,7 +723,6 @@ static int ZEND_FASTCALL  ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                }
        } else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) {
                int should_change_scope = 0;
-               zval *ret;
 
                if (fbc->common.scope) {
                        should_change_scope = 1;
@@ -1255,6 +1433,9 @@ static int ZEND_FASTCALL  ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
                        do {
                                switch (opline->opcode) {
                                        case ZEND_DO_FCALL:
+                                       case ZEND_DO_ICALL:
+                                       case ZEND_DO_UCALL:
+                                       case ZEND_DO_FCALL_BY_NAME:
                                                level++;
                                                break;
                                        case ZEND_INIT_FCALL:
@@ -1301,6 +1482,9 @@ static int ZEND_FASTCALL  ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
                                do {
                                        switch (opline->opcode) {
                                                case ZEND_DO_FCALL:
+                                               case ZEND_DO_ICALL:
+                                               case ZEND_DO_UCALL:
+                                               case ZEND_DO_FCALL_BY_NAME:
                                                        level++;
                                                        break;
                                                case ZEND_INIT_FCALL:
@@ -19437,7 +19621,10 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O
                                        opline->opcode == ZEND_NEW
                                ) {
                                        nesting++;
-                               } else if (opline->opcode == ZEND_DO_FCALL) {
+                               } else if (opline->opcode == ZEND_DO_FCALL ||
+                                          opline->opcode == ZEND_DO_ICALL ||
+                                          opline->opcode == ZEND_DO_UCALL ||
+                                          opline->opcode == ZEND_DO_FCALL_BY_NAME) {
                                        nesting--;
                                }
                        } while (nesting);
@@ -21644,7 +21831,10 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO
                                        opline->opcode == ZEND_NEW
                                ) {
                                        nesting++;
-                               } else if (opline->opcode == ZEND_DO_FCALL) {
+                               } else if (opline->opcode == ZEND_DO_FCALL ||
+                                          opline->opcode == ZEND_DO_ICALL ||
+                                          opline->opcode == ZEND_DO_UCALL ||
+                                          opline->opcode == ZEND_DO_FCALL_BY_NAME) {
                                        nesting--;
                                }
                        } while (nesting);
@@ -23035,7 +23225,10 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_
                                        opline->opcode == ZEND_NEW
                                ) {
                                        nesting++;
-                               } else if (opline->opcode == ZEND_DO_FCALL) {
+                               } else if (opline->opcode == ZEND_DO_FCALL ||
+                                          opline->opcode == ZEND_DO_ICALL ||
+                                          opline->opcode == ZEND_DO_UCALL ||
+                                          opline->opcode == ZEND_DO_FCALL_BY_NAME) {
                                        nesting--;
                                }
                        } while (nesting);
@@ -26527,7 +26720,10 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD
                                        opline->opcode == ZEND_NEW
                                ) {
                                        nesting++;
-                               } else if (opline->opcode == ZEND_DO_FCALL) {
+                               } else if (opline->opcode == ZEND_DO_FCALL ||
+                                          opline->opcode == ZEND_DO_ICALL ||
+                                          opline->opcode == ZEND_DO_UCALL ||
+                                          opline->opcode == ZEND_DO_FCALL_BY_NAME) {
                                        nesting--;
                                }
                        } while (nesting);
@@ -30756,7 +30952,10 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H
                                        opline->opcode == ZEND_NEW
                                ) {
                                        nesting++;
-                               } else if (opline->opcode == ZEND_DO_FCALL) {
+                               } else if (opline->opcode == ZEND_DO_FCALL ||
+                                          opline->opcode == ZEND_DO_ICALL ||
+                                          opline->opcode == ZEND_DO_UCALL ||
+                                          opline->opcode == ZEND_DO_FCALL_BY_NAME) {
                                        nesting--;
                                }
                        } while (nesting);
@@ -32726,7 +32925,10 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCO
                                        opline->opcode == ZEND_NEW
                                ) {
                                        nesting++;
-                               } else if (opline->opcode == ZEND_DO_FCALL) {
+                               } else if (opline->opcode == ZEND_DO_FCALL ||
+                                          opline->opcode == ZEND_DO_ICALL ||
+                                          opline->opcode == ZEND_DO_UCALL ||
+                                          opline->opcode == ZEND_DO_FCALL_BY_NAME) {
                                        nesting--;
                                }
                        } while (nesting);
@@ -34399,7 +34601,10 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER(ZEND_O
                                        opline->opcode == ZEND_NEW
                                ) {
                                        nesting++;
-                               } else if (opline->opcode == ZEND_DO_FCALL) {
+                               } else if (opline->opcode == ZEND_DO_FCALL ||
+                                          opline->opcode == ZEND_DO_ICALL ||
+                                          opline->opcode == ZEND_DO_UCALL ||
+                                          opline->opcode == ZEND_DO_FCALL_BY_NAME) {
                                        nesting--;
                                }
                        } while (nesting);
@@ -36014,7 +36219,10 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCO
                                        opline->opcode == ZEND_NEW
                                ) {
                                        nesting++;
-                               } else if (opline->opcode == ZEND_DO_FCALL) {
+                               } else if (opline->opcode == ZEND_DO_FCALL ||
+                                          opline->opcode == ZEND_DO_ICALL ||
+                                          opline->opcode == ZEND_DO_UCALL ||
+                                          opline->opcode == ZEND_DO_FCALL_BY_NAME) {
                                        nesting--;
                                }
                        } while (nesting);
@@ -36674,7 +36882,10 @@ static int ZEND_FASTCALL  ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_
                                        opline->opcode == ZEND_NEW
                                ) {
                                        nesting++;
-                               } else if (opline->opcode == ZEND_DO_FCALL) {
+                               } else if (opline->opcode == ZEND_DO_FCALL ||
+                                          opline->opcode == ZEND_DO_ICALL ||
+                                          opline->opcode == ZEND_DO_UCALL ||
+                                          opline->opcode == ZEND_DO_FCALL_BY_NAME) {
                                        nesting--;
                                }
                        } while (nesting);
@@ -40155,81 +40366,81 @@ void zend_init_opcodes_handlers(void)
        ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_ICALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_UCALL_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
+       ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
index 1ab2a9e0fa0289a758a9d21db90842055edc3f21..991e56bc77aa514696c2b12484f8edcff98ca128 100644 (file)
@@ -151,9 +151,9 @@ const char *zend_vm_opcodes_map[171] = {
        "ZEND_FE_FETCH_RW",
        "ZEND_FE_FREE",
        "ZEND_INIT_DYNAMIC_CALL",
-       NULL,
-       NULL,
-       NULL,
+       "ZEND_DO_ICALL",
+       "ZEND_DO_UCALL",
+       "ZEND_DO_FCALL_BY_NAME",
        "ZEND_PRE_INC_OBJ",
        "ZEND_PRE_DEC_OBJ",
        "ZEND_POST_INC_OBJ",
index d21ff08e7f92f33b62b87cdf330be958f50dd2f4..367e52150c0b98c2ca001784a397fac528d5ad33 100644 (file)
@@ -153,6 +153,9 @@ END_EXTERN_C()
 #define ZEND_FE_FETCH_RW                     126
 #define ZEND_FE_FREE                         127
 #define ZEND_INIT_DYNAMIC_CALL               128
+#define ZEND_DO_ICALL                        129
+#define ZEND_DO_UCALL                        130
+#define ZEND_DO_FCALL_BY_NAME                131
 #define ZEND_PRE_INC_OBJ                     132
 #define ZEND_PRE_DEC_OBJ                     133
 #define ZEND_POST_INC_OBJ                    134
index 4db48944e170fa6606f26dc4c21bfd6765fdbd9f..0922d6e8098f8ab7de2e49b0338ef465a2686a91 100644 (file)
@@ -1828,6 +1828,9 @@ static void zend_t_usage(zend_code_block *block, zend_op_array *op_array, char *
                                        case ZEND_ASSIGN:
                                        case ZEND_ASSIGN_REF:
                                        case ZEND_DO_FCALL:
+                                       case ZEND_DO_ICALL:
+                                       case ZEND_DO_UCALL:
+                                       case ZEND_DO_FCALL_BY_NAME:
                                                if (ZEND_RESULT_TYPE(opline) == IS_VAR) {
                                                        ZEND_RESULT_TYPE(opline) |= EXT_TYPE_UNUSED;
                                                }
index a83adab5ec1a2e99efba7d807772c44f7044ce64..270e38d59481b37eebbc7454d9bc132e65b09acb 100644 (file)
@@ -75,6 +75,9 @@ void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
                                call++;
                                break;
                        case ZEND_DO_FCALL:
+                       case ZEND_DO_ICALL:
+                       case ZEND_DO_UCALL:
+                       case ZEND_DO_FCALL_BY_NAME:
                                call--;
                                if (call_stack[call].func && call_stack[call].opline) {
                                        zend_op *fcall = call_stack[call].opline;
@@ -85,6 +88,7 @@ void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
                                                Z_CACHE_SLOT(op_array->literals[fcall->op2.constant + 1]) = Z_CACHE_SLOT(op_array->literals[fcall->op2.constant]);
                                                literal_dtor(&ZEND_OP2_LITERAL(fcall));
                                                fcall->op2.constant = fcall->op2.constant + 1;
+                                               opline->opcode = zend_get_call_op(ZEND_INIT_FCALL, call_stack[call].func);
                                        } else if (fcall->opcode == ZEND_INIT_NS_FCALL_BY_NAME) {
                                                fcall->opcode = ZEND_INIT_FCALL;
                                                fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func);
@@ -92,6 +96,7 @@ void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
                                                literal_dtor(&op_array->literals[fcall->op2.constant]);
                                                literal_dtor(&op_array->literals[fcall->op2.constant + 2]);
                                                fcall->op2.constant = fcall->op2.constant + 1;
+                                               opline->opcode = zend_get_call_op(ZEND_INIT_FCALL, call_stack[call].func);
                                        } else {
                                                ZEND_ASSERT(0);
                                        }
index 341e80501b44fa46ee7c155c74c12d160030124f..990b845d4344da6d47a797f83b81d95885ff6327 100644 (file)
@@ -341,7 +341,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
                        }
                        break;
 
-               case ZEND_DO_FCALL: {
+               case ZEND_DO_ICALL: {
                        zend_op *send1_opline = opline - 1;
                        zend_op *send2_opline = NULL;
                        zend_op *init_opline = NULL;
index cdcbfeda560198eb9ad6635f242afb37cca83f5a..3aa90fb738622c90744efd5d3d335d1f828f3d5d 100644 (file)
@@ -1836,6 +1836,11 @@ static void accel_activate(void)
                return;
        }
 
+       if (!ZCG(function_table).nTableSize) {
+               zend_hash_init(&ZCG(function_table), zend_hash_num_elements(CG(function_table)), NULL, ZEND_FUNCTION_DTOR, 1);
+               zend_accel_copy_internal_functions();
+       }
+
        SHM_UNPROTECT();
        /* PHP-5.4 and above return "double", but we use 1 sec precision */
        ZCG(auto_globals_mask) = 0;
@@ -2257,8 +2262,6 @@ static void accel_globals_ctor(zend_accel_globals *accel_globals)
        ZEND_TSRMLS_CACHE_UPDATE();
 #endif
        memset(accel_globals, 0, sizeof(zend_accel_globals));
-       zend_hash_init(&accel_globals->function_table, zend_hash_num_elements(CG(function_table)), NULL, ZEND_FUNCTION_DTOR, 1);
-       zend_accel_copy_internal_functions();
 }
 
 static void accel_globals_internal_func_dtor(zval *zv)
@@ -2268,8 +2271,10 @@ static void accel_globals_internal_func_dtor(zval *zv)
 
 static void accel_globals_dtor(zend_accel_globals *accel_globals)
 {
-       accel_globals->function_table.pDestructor = accel_globals_internal_func_dtor;
-       zend_hash_destroy(&accel_globals->function_table);
+       if (accel_globals->function_table.nTableSize) {
+               accel_globals->function_table.pDestructor = accel_globals_internal_func_dtor;
+               zend_hash_destroy(&accel_globals->function_table);
+       }
 }
 
 static int accel_startup(zend_extension *extension)
@@ -2422,11 +2427,6 @@ static int accel_startup(zend_extension *extension)
                zend_accel_blacklist_load(&accel_blacklist, ZCG(accel_directives.user_blacklist_filename));
        }
 
-#if 0
-       /* FIXME: We probably don't need it here */
-       zend_accel_copy_internal_functions();
-#endif
-
        return SUCCESS;
 }
 
index 6e492b7aaa4a3343222dfd4080570430895454eb..72cb2e018c46161150bd3638533d8c59882d672d 100644 (file)
@@ -1454,7 +1454,10 @@ next:
                PHPDBG_G(last_line) = execute_data->opline->lineno;
 
                /* stupid hack to make zend_do_fcall_common_helper return ZEND_VM_ENTER() instead of recursively calling zend_execute() and eventually segfaulting */
-               if (execute_data->opline->opcode == ZEND_DO_FCALL && execute_data->func->type == ZEND_USER_FUNCTION) {
+               if ((execute_data->opline->opcode == ZEND_DO_FCALL ||
+                    execute_data->opline->opcode == ZEND_DO_UCALL ||
+                    execute_data->opline->opcode == ZEND_DO_FCALL_BY_NAME) &&
+                   execute_data->func->type == ZEND_USER_FUNCTION) {
                        zend_execute_ex = execute_ex;
                }
                PHPDBG_G(vmret) = execute_data->opline->handler(execute_data);