From: Nikita Popov Date: Mon, 27 Apr 2020 10:50:24 +0000 (+0200) Subject: Use information about classes returned by internal functions X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a447897db08ebed361a7d18c8ea0d10089040460;p=php Use information about classes returned by internal functions --- diff --git a/ext/opcache/Optimizer/zend_func_info.c b/ext/opcache/Optimizer/zend_func_info.c index c9c567ffbf..880e2238d4 100644 --- a/ext/opcache/Optimizer/zend_func_info.c +++ b/ext/opcache/Optimizer/zend_func_info.c @@ -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 diff --git a/ext/opcache/Optimizer/zend_func_info.h b/ext/opcache/Optimizer/zend_func_info.h index 0f4fcea092..9599c29fa1 100644 --- a/ext/opcache/Optimizer/zend_func_info.h +++ b/ext/opcache/Optimizer/zend_func_info.h @@ -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); diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index f868f78265..af8a3996de 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -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; diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 6ba439239b..173b831642 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -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)) {