]> granicus.if.org Git - php/commitdiff
Use information about classes returned by internal functions
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 27 Apr 2020 10:50:24 +0000 (12:50 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 27 Apr 2020 10:50:24 +0000 (12:50 +0200)
ext/opcache/Optimizer/zend_func_info.c
ext/opcache/Optimizer/zend_func_info.h
ext/opcache/Optimizer/zend_inference.c
ext/opcache/jit/zend_jit_x86.dasc

index c9c567ffbfe34d1364ead4258428ba42cbd6fe5d..880e2238d43043e29a43166b65d1037a59cf28b4 100644 (file)
@@ -886,10 +886,14 @@ static const func_info_t func_infos[] = {
 static HashTable func_info;
 int zend_func_info_rid = -1;
 
-uint32_t zend_get_func_info(const zend_call_info *call_info, const zend_ssa *ssa)
+uint32_t zend_get_func_info(
+               const zend_call_info *call_info, const zend_ssa *ssa,
+               zend_class_entry **ce, zend_bool *ce_is_instanceof)
 {
        uint32_t ret = 0;
        const zend_function *callee_func = call_info->callee_func;
+       *ce = NULL;
+       *ce_is_instanceof = 0;
 
        if (callee_func->type == ZEND_INTERNAL_FUNCTION) {
                zval *zv;
@@ -909,8 +913,8 @@ uint32_t zend_get_func_info(const zend_call_info *call_info, const zend_ssa *ssa
                }
 
                if (callee_func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
-                       zend_class_entry *ce; // TODO: Use the CE.
-                       ret = zend_fetch_arg_info_type(NULL, callee_func->common.arg_info - 1, &ce);
+                       ret = zend_fetch_arg_info_type(NULL, callee_func->common.arg_info - 1, ce);
+                       *ce_is_instanceof = 1;
                } else {
 #if 0
                        fprintf(stderr, "Unknown internal function '%s'\n", func->common.function_name);
@@ -926,6 +930,8 @@ uint32_t zend_get_func_info(const zend_call_info *call_info, const zend_ssa *ssa
                zend_func_info *info = ZEND_FUNC_INFO((zend_op_array*)callee_func);
                if (info) {
                        ret = info->return_info.type;
+                       *ce = info->return_info.ce;
+                       *ce_is_instanceof = info->return_info.is_instanceof;
                }
                if (!ret) {
                        ret = MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF
index 0f4fcea092de0e599398a614ee3f208b1a922b30..9599c29fa19f7bb381c24f25bf537c85b5ddb057 100644 (file)
@@ -49,7 +49,9 @@ BEGIN_EXTERN_C()
 
 extern int zend_func_info_rid;
 
-uint32_t zend_get_func_info(const zend_call_info *call_info, const zend_ssa *ssa);
+uint32_t zend_get_func_info(
+       const zend_call_info *call_info, const zend_ssa *ssa,
+       zend_class_entry **ce, zend_bool *ce_is_instanceof);
 
 int zend_func_info_startup(void);
 int zend_func_info_shutdown(void);
index f868f78265d647ef69aa16a84cddf2f57cc0e23d..af8a3996de2d3ccca314160c1acced52724a8f8b 100644 (file)
@@ -3436,16 +3436,13 @@ static zend_always_inline int _zend_update_type_info(
                                if (!call_info) {
                                        goto unknown_opcode;
                                }
-                               tmp = zend_get_func_info(call_info, ssa);
+
+                               zend_class_entry *ce;
+                               zend_bool ce_is_instanceof;
+                               tmp = zend_get_func_info(call_info, ssa, &ce, &ce_is_instanceof);
                                UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
-                               if (call_info->callee_func->type == ZEND_USER_FUNCTION) {
-                                       func_info = ZEND_FUNC_INFO(&call_info->callee_func->op_array);
-                                       if (func_info) {
-                                               UPDATE_SSA_OBJ_TYPE(
-                                                       func_info->return_info.ce,
-                                                       func_info->return_info.is_instanceof,
-                                                       ssa_op->result_def);
-                                       }
+                               if (ce) {
+                                       UPDATE_SSA_OBJ_TYPE(ce, ce_is_instanceof, ssa_op->result_def);
                                }
                        }
                        break;
index 6ba439239b32c3185d57f2d6e8ef15c9de34d9b8..173b83164208a68e3bfede68bea7e680918f3d4e 100644 (file)
@@ -8463,8 +8463,10 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
                |1:
 
                if (!RETURN_VALUE_USED(opline)) {
+                       zend_class_entry *ce;
+                       zend_bool ce_is_instanceof;
                        uint32_t func_info = call_info ?
-                               zend_get_func_info(call_info, ssa) :
+                               zend_get_func_info(call_info, ssa, &ce, &ce_is_instanceof) :
                                (MAY_BE_ANY|MAY_BE_REF|MAY_BE_RC1|MAY_BE_RCN);
 
                        if (func_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) {