From ea3a317659b7c7418dabb4d78ae88e74d810812b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 18 Jun 2020 17:01:29 +0200 Subject: [PATCH 1/7] Fix race condition in FPM tests The newly de-XFAILed tests have a race condition. Make sure we terminate only after expecting all the log lines. --- sapi/fpm/tests/log-bwd-multiple-msgs-stdout-stderr.phpt | 2 +- sapi/fpm/tests/log-bwd-multiple-msgs.phpt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sapi/fpm/tests/log-bwd-multiple-msgs-stdout-stderr.phpt b/sapi/fpm/tests/log-bwd-multiple-msgs-stdout-stderr.phpt index 376a972bacac0..b1b8a65c686e3 100644 --- a/sapi/fpm/tests/log-bwd-multiple-msgs-stdout-stderr.phpt +++ b/sapi/fpm/tests/log-bwd-multiple-msgs-stdout-stderr.phpt @@ -34,9 +34,9 @@ $tester->start(); $tester->expectLogStartNotices(); $tester->request()->expectEmptyBody(); $tester->request()->expectEmptyBody(); -$tester->terminate(); $tester->expectLogLine('msg 1 - ', false); $tester->expectLogLine('msg 2 - msg 3', true); +$tester->terminate(); $tester->close(); ?> diff --git a/sapi/fpm/tests/log-bwd-multiple-msgs.phpt b/sapi/fpm/tests/log-bwd-multiple-msgs.phpt index b221a8344c8e0..d328aff9db243 100644 --- a/sapi/fpm/tests/log-bwd-multiple-msgs.phpt +++ b/sapi/fpm/tests/log-bwd-multiple-msgs.phpt @@ -34,9 +34,9 @@ $tester->start(); $tester->expectLogStartNotices(); $tester->request()->expectEmptyBody(); $tester->request()->expectEmptyBody(); -$tester->terminate(); $tester->expectLogLine('msg 1 - msg 2 - msg 3'); $tester->expectLogLine('msg 1 - msg 2 - msg 3'); +$tester->terminate(); $tester->close(); ?> Done From 48e16a9dba12cae799583ec145d586d09e7cc5a1 Mon Sep 17 00:00:00 2001 From: moliata Date: Thu, 18 Jun 2020 15:24:27 +0300 Subject: [PATCH 2/7] Use ZEND_TOSTRING_FUNC_NAME Closes GH-5736. --- Zend/zend_compile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index a34b1d8bea99b..f65e4a94ec8ef 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -6465,7 +6465,7 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /* } zend_compile_params(params_ast, return_type_ast, - is_method && zend_string_equals_literal_ci(decl->name, "__toString") ? IS_STRING : 0); + is_method && zend_string_equals_literal(method_lcname, ZEND_TOSTRING_FUNC_NAME) ? IS_STRING : 0); if (CG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) { zend_mark_function_as_generator(); zend_emit_op(NULL, ZEND_GENERATOR_CREATE, NULL, NULL); From 607567b9cd750a018f7af2d22ea63bf42be106fa Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 18 Jun 2020 17:10:22 +0200 Subject: [PATCH 3/7] Call zpp in enchant_broker_*_dict_path with libenchant-2 Even if the function is a dummy, we still need to call zpp to comply with arginfo. --- ext/enchant/enchant.c | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/ext/enchant/enchant.c b/ext/enchant/enchant.c index 5f7e043730b02..19918e8a84da6 100644 --- a/ext/enchant/enchant.c +++ b/ext/enchant/enchant.c @@ -346,13 +346,11 @@ PHP_FUNCTION(enchant_broker_get_error) } /* }}} */ -#if HAVE_ENCHANT_BROKER_SET_PARAM /* {{{ proto bool enchant_broker_set_dict_path(resource broker, int dict_type, string value) Set the directory path for a given backend, works with ispell and myspell */ PHP_FUNCTION(enchant_broker_set_dict_path) { zval *broker; - enchant_broker *pbroker; zend_long dict_type; char *value; size_t value_len; @@ -361,6 +359,8 @@ PHP_FUNCTION(enchant_broker_set_dict_path) RETURN_THROWS(); } +#if HAVE_ENCHANT_BROKER_SET_PARAM + enchant_broker *pbroker; if (!value_len) { RETURN_FALSE; } @@ -383,6 +383,7 @@ PHP_FUNCTION(enchant_broker_set_dict_path) default: RETURN_FALSE; } +#endif } /* }}} */ @@ -392,14 +393,15 @@ PHP_FUNCTION(enchant_broker_set_dict_path) PHP_FUNCTION(enchant_broker_get_dict_path) { zval *broker; - enchant_broker *pbroker; zend_long dict_type; - char *value; if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ol", &broker, enchant_broker_ce, &dict_type) == FAILURE) { RETURN_THROWS(); } +#if HAVE_ENCHANT_BROKER_SET_PARAM + enchant_broker *pbroker; + char *value; PHP_ENCHANT_GET_BROKER; switch (dict_type) { @@ -423,26 +425,9 @@ PHP_FUNCTION(enchant_broker_get_dict_path) } RETURN_STRING(value); +#endif } /* }}} */ -#else -/* {{{ proto bool enchant_broker_set_dict_path(resource broker, int dict_type, string value) - Set the directory path for a given backend, works with ispell and myspell */ -PHP_FUNCTION(enchant_broker_set_dict_path) -{ - RETURN_FALSE; -} -/* }}} */ - - -/* {{{ proto string enchant_broker_get_dict_path(resource broker, int dict_type) - Get the directory path for a given backend, works with ispell and myspell */ -PHP_FUNCTION(enchant_broker_get_dict_path) -{ - RETURN_FALSE; -} -/* }}} */ -#endif /* {{{ proto array enchant_broker_list_dicts(resource broker) Lists the dictionaries available for the given broker */ From 090bddb93488b6bcf411e970afe77d96f86f4ac8 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 18 Jun 2020 16:25:16 +0200 Subject: [PATCH 4/7] Update libzip on macos We need libzip 1.7.1, because libzip 1.7.0 is broken. Closes GH-5737. --- azure/macos/brew.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/azure/macos/brew.yml b/azure/macos/brew.yml index df4c5a532d740..02cb736d0262e 100644 --- a/azure/macos/brew.yml +++ b/azure/macos/brew.yml @@ -2,6 +2,8 @@ parameters: packages: '' steps: + - script: brew update + displayName: 'Update Homebrew' - script: | brew install pkg-config \ autoconf \ @@ -23,11 +25,12 @@ steps: zlib \ t1lib \ gd \ - libzip \ gmp \ tidyp \ libxml2 \ libxslt \ postgresql + # Make sure we don't get broken libzip 1.7.0 + brew upgrade libzip brew link icu4c gettext --force displayName: 'Install Build Dependencies' From f3e6b123dc5da6a92960fbe21000b53a3450e64a Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 18 Jun 2020 16:45:39 +0200 Subject: [PATCH 5/7] check for broken libzip versions Closes GH-5738. --- ext/zip/config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/zip/config.m4 b/ext/zip/config.m4 index 0b151b7f2ae32..15fc12f2a2778 100644 --- a/ext/zip/config.m4 +++ b/ext/zip/config.m4 @@ -4,7 +4,7 @@ PHP_ARG_WITH([zip], [Include Zip read/write support])]) if test "$PHP_ZIP" != "no"; then - PKG_CHECK_MODULES([LIBZIP], [libzip >= 0.11]) + PKG_CHECK_MODULES([LIBZIP], [libzip >= 0.11 libzip != 1.3.1 libzip != 1.7.0]) PHP_EVAL_INCLINE($LIBZIP_CFLAGS) PHP_EVAL_LIBLINE($LIBZIP_LIBS, ZIP_SHARED_LIBADD) From 3a9a8df3fd46b0f359549cc02d1abc8610ef6b76 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 18 Jun 2020 17:30:03 +0200 Subject: [PATCH 6/7] Fix CLI test if linked against libedit The error message changed here. --- sapi/cli/tests/017.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sapi/cli/tests/017.phpt b/sapi/cli/tests/017.phpt index 4cc80a4b0aeea..6c9a792476737 100644 --- a/sapi/cli/tests/017.phpt +++ b/sapi/cli/tests/017.phpt @@ -103,7 +103,7 @@ Snippet no. 5: Interactive shell -Parse error: syntax error, unexpected ')' in php shell code on line 1 +Parse error: Unmatched ')' in php shell code on line 1 Done From 6fa126e966d343b45f84d9eac114c14b73aef5a8 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 18 Jun 2020 18:54:32 +0300 Subject: [PATCH 7/7] MAY_BE_INDIRECT inference --- Zend/zend_type_info.h | 1 + ext/opcache/Optimizer/zend_inference.c | 27 +++++++++++++++++++++++-- ext/opcache/Optimizer/zend_inference.h | 2 +- ext/opcache/jit/zend_jit_x86.dasc | 28 ++++++++++++-------------- 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/Zend/zend_type_info.h b/Zend/zend_type_info.h index bace8014bfc3f..9dc90d142b4ed 100644 --- a/Zend/zend_type_info.h +++ b/Zend/zend_type_info.h @@ -61,5 +61,6 @@ #define MAY_BE_ARRAY_KEY_ANY (MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_KEY_STRING) #define MAY_BE_CLASS (1<<23) +#define MAY_BE_INDIRECT (1<<24) #endif /* ZEND_TYPE_INFO_H */ diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index 0c0a2921c967d..5a29165aec0fb 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -1983,6 +1983,9 @@ uint32_t zend_array_element_type(uint32_t t1, int write, int insert) tmp |= MAY_BE_RC1 | MAY_BE_RCN; } } + if (write) { + tmp |= MAY_BE_INDIRECT; + } } if (t1 & MAY_BE_STRING) { tmp |= MAY_BE_STRING | MAY_BE_RC1; @@ -3398,7 +3401,7 @@ static zend_always_inline int _zend_update_type_info( tmp = zend_fetch_prop_type(script, zend_fetch_prop_info(op_array, ssa, opline, ssa_op), &ce); if (opline->result_type != IS_TMP_VAR) { - tmp |= MAY_BE_REF; + tmp |= MAY_BE_REF | MAY_BE_INDIRECT; } UPDATE_SSA_TYPE(tmp, ssa_op->result_def); if (ce) { @@ -3415,7 +3418,7 @@ static zend_always_inline int _zend_update_type_info( tmp = zend_fetch_prop_type(script, zend_fetch_static_prop_info(script, op_array, ssa, opline), &ce); if (opline->result_type != IS_TMP_VAR) { - tmp |= MAY_BE_REF; + tmp |= MAY_BE_REF | MAY_BE_INDIRECT; } UPDATE_SSA_TYPE(tmp, ssa_op->result_def); if (ce) { @@ -3524,6 +3527,26 @@ static zend_always_inline int _zend_update_type_info( tmp |= MAY_BE_RC1 | MAY_BE_RCN; } else { tmp |= MAY_BE_REF | MAY_BE_RC1 | MAY_BE_RCN; + switch (opline->opcode) { + case ZEND_FETCH_W: + case ZEND_FETCH_RW: + case ZEND_FETCH_FUNC_ARG: + case ZEND_FETCH_UNSET: + case ZEND_FETCH_DIM_W: + case ZEND_FETCH_DIM_RW: + case ZEND_FETCH_DIM_FUNC_ARG: + case ZEND_FETCH_DIM_UNSET: + case ZEND_FETCH_OBJ_W: + case ZEND_FETCH_OBJ_RW: + case ZEND_FETCH_OBJ_FUNC_ARG: + case ZEND_FETCH_OBJ_UNSET: + case ZEND_FETCH_STATIC_PROP_W: + case ZEND_FETCH_STATIC_PROP_RW: + case ZEND_FETCH_STATIC_PROP_FUNC_ARG: + case ZEND_FETCH_STATIC_PROP_UNSET: + tmp |= MAY_BE_INDIRECT; + break; + } } UPDATE_SSA_TYPE(tmp, ssa_op->result_def); } diff --git a/ext/opcache/Optimizer/zend_inference.h b/ext/opcache/Optimizer/zend_inference.h index da103e4bb5280..525159a72b4e0 100644 --- a/ext/opcache/Optimizer/zend_inference.h +++ b/ext/opcache/Optimizer/zend_inference.h @@ -195,7 +195,7 @@ static zend_always_inline uint32_t get_ssa_var_info(const zend_ssa *ssa, int ssa if (ssa->var_info && ssa_var_num >= 0) { return ssa->var_info[ssa_var_num].type; } else { - return MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF; + return MAY_BE_UNDEF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_REF | MAY_BE_INDIRECT | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF; } } diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 576bb7badbc03..b4306f5bdba97 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -1323,7 +1323,7 @@ static void* dasm_labels[zend_lb_MAX]; // zval should be in FCARG1a |.macro ZVAL_DTOR_FUNC, var_info, opline // arg1 must be in FCARG1a || do { -|| if (has_concrete_type((var_info) & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { +|| if (has_concrete_type((var_info) & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_INDIRECT))) { || zend_uchar type = concrete_type((var_info) & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)); || if (type == IS_STRING && !ZEND_DEBUG) { | EXT_CALL _efree, r0 @@ -1355,7 +1355,7 @@ static void* dasm_labels[zend_lb_MAX]; |.macro ZVAL_PTR_DTOR, addr, op_info, gc, cold, opline || if ((op_info) & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) { -|| if ((op_info) & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_OBJECT|MAY_BE_RESOURCE))) { +|| if ((op_info) & ((MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_INDIRECT)-(MAY_BE_OBJECT|MAY_BE_RESOURCE))) { | // if (Z_REFCOUNTED_P(cv)) { || if (cold) { | IF_ZVAL_REFCOUNTED addr, >1 @@ -8916,12 +8916,15 @@ static int zend_jit_send_ref(dasm_State **Dst, const zend_op *opline, const zend } if (opline->op1_type == IS_VAR) { - | LOAD_ZVAL_ADDR r0, op1_addr - | // if (EXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) { - | IF_NOT_Z_TYPE r0, IS_INDIRECT, >1 - | // ret = Z_INDIRECT_P(ret); - | GET_Z_PTR r0, r0 - |1: + if (op1_info & MAY_BE_INDIRECT) { + | LOAD_ZVAL_ADDR r0, op1_addr + | // if (EXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) { + | IF_NOT_Z_TYPE r0, IS_INDIRECT, >1 + | // ret = Z_INDIRECT_P(ret); + | GET_Z_PTR r0, r0 + |1: + op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0); + } } else if (opline->op1_type == IS_CV) { if (op1_info & MAY_BE_UNDEF) { if (op1_info & (MAY_BE_ANY|MAY_BE_REF)) { @@ -8939,13 +8942,8 @@ static int zend_jit_send_ref(dasm_State **Dst, const zend_op *opline, const zend if (op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) { if (op1_info & MAY_BE_REF) { - if (opline->op1_type == IS_VAR) { - | IF_NOT_Z_TYPE r0, IS_REFERENCE, >2 - | GET_Z_PTR r1, r0 - } else { - | IF_NOT_ZVAL_TYPE op1_addr, IS_REFERENCE, >2 - | GET_ZVAL_PTR r1, op1_addr - } + | IF_NOT_ZVAL_TYPE op1_addr, IS_REFERENCE, >2 + | GET_ZVAL_PTR r1, op1_addr | GC_ADDREF r1 | SET_ZVAL_PTR arg_addr, r1 | SET_ZVAL_TYPE_INFO arg_addr, IS_REFERENCE_EX