mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Compare commits
1 commit
master
...
php-8.3.24
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4d0d451702 |
10620 changed files with 760333 additions and 1077507 deletions
|
@ -46,6 +46,8 @@ jobs:
|
|||
libicu-dev \
|
||||
libtidy-dev \
|
||||
libenchant-2-dev \
|
||||
libaspell-dev \
|
||||
libpspell-dev \
|
||||
libsasl2-dev \
|
||||
libxpm-dev \
|
||||
libzip-dev \
|
||||
|
@ -53,6 +55,8 @@ jobs:
|
|||
libsqlite3-dev \
|
||||
libwebp-dev \
|
||||
libonig-dev \
|
||||
libkrb5-dev \
|
||||
libgssapi-krb5-2 \
|
||||
libcurl4-openssl-dev \
|
||||
libxml2-dev \
|
||||
libxslt1-dev \
|
||||
|
@ -67,6 +71,7 @@ jobs:
|
|||
`#snmp-mibs-downloader` \
|
||||
freetds-dev \
|
||||
`#unixodbc-dev` \
|
||||
libc-client-dev \
|
||||
dovecot-core \
|
||||
dovecot-pop3d \
|
||||
dovecot-imapd \
|
||||
|
@ -90,6 +95,7 @@ jobs:
|
|||
--prefix=/usr \
|
||||
--enable-phpdbg \
|
||||
--enable-fpm \
|
||||
--enable-opcache \
|
||||
--with-pdo-mysql=mysqlnd \
|
||||
--with-mysqli=mysqlnd \
|
||||
--with-pgsql \
|
||||
|
@ -105,6 +111,7 @@ jobs:
|
|||
--enable-exif \
|
||||
--with-zip \
|
||||
--with-zlib \
|
||||
--with-zlib-dir=/usr \
|
||||
--enable-soap \
|
||||
--enable-xmlreader \
|
||||
--with-xsl \
|
||||
|
@ -124,7 +131,9 @@ jobs:
|
|||
--enable-bcmath \
|
||||
--enable-calendar \
|
||||
--enable-ftp \
|
||||
--with-pspell=/usr \
|
||||
--with-enchant=/usr \
|
||||
--with-kerberos \
|
||||
--enable-sysvmsg \
|
||||
--with-ffi \
|
||||
--enable-zend-test \
|
||||
|
@ -143,7 +152,12 @@ jobs:
|
|||
--with-qdbm \
|
||||
--with-snmp \
|
||||
`#--with-unixODBC` \
|
||||
--with-imap \
|
||||
--with-kerberos \
|
||||
--with-imap-ssl \
|
||||
`#--with-pdo-odbc=unixODBC,/usr` \
|
||||
`#--with-pdo-oci=shared,instantclient,/opt/oracle/instantclient` \
|
||||
`#--with-oci8=shared,instantclient,/opt/oracle/instantclient` \
|
||||
--with-config-file-path=/etc \
|
||||
--with-config-file-scan-dir=/etc/php.d \
|
||||
--with-pdo-firebird \
|
||||
|
@ -167,8 +181,9 @@ jobs:
|
|||
no_output_timeout: 30m
|
||||
command: |
|
||||
sapi/cli/php run-tests.php \
|
||||
-d zend_extension=opcache.so \
|
||||
-d opcache.enable_cli=1 \
|
||||
-d opcache.jit_buffer_size=64M \
|
||||
-d opcache.jit_buffer_size=16M \
|
||||
-d opcache.jit=tracing \
|
||||
-d zend_test.observer.enabled=1 \
|
||||
-d zend_test.observer.show_output=0 \
|
||||
|
|
|
@ -32,7 +32,3 @@ max_line_length = 80
|
|||
|
||||
[*.patch]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.rst]
|
||||
indent_style = space
|
||||
max_line_length = 100
|
||||
|
|
7
.gitattributes
vendored
7
.gitattributes
vendored
|
@ -21,14 +21,9 @@
|
|||
|
||||
# Collapse generated files within git and pull request diff.
|
||||
**/*_arginfo.h linguist-generated -diff
|
||||
/main/debug_gdb_scripts.c linguist-generated -diff
|
||||
/Zend/zend_vm_execute.h linguist-generated -diff
|
||||
/Zend/zend_vm_handlers.h linguist-generated -diff
|
||||
/Zend/zend_vm_opcodes.[ch] linguist-generated -diff
|
||||
|
||||
# The OSS fuzz files are binary
|
||||
# The OSS fuzz files are bunary
|
||||
/ext/date/tests/ossfuzz*.txt binary
|
||||
|
||||
# Vendored libraries
|
||||
/ext/lexbor/lexbor linguist-vendored
|
||||
/ext/uri/uriparser linguist-vendored
|
||||
|
|
5
.github/CODEOWNERS
vendored
5
.github/CODEOWNERS
vendored
|
@ -16,7 +16,7 @@
|
|||
|
||||
/.github @TimWolla
|
||||
/build/gen_stub.php @kocsismate
|
||||
/ext/bcmath @nielsdos @SakiTakamachi
|
||||
/ext/bcmath @Girgias @nielsdos @SakiTakamachi
|
||||
/ext/curl @adoy
|
||||
/ext/date @derickr
|
||||
/ext/dba @Girgias
|
||||
|
@ -25,9 +25,9 @@
|
|||
/ext/gd @devnexen
|
||||
/ext/gettext @devnexen
|
||||
/ext/gmp @Girgias
|
||||
/ext/imap @Girgias
|
||||
/ext/intl @devnexen
|
||||
/ext/json @bukka
|
||||
/ext/lexbor @kocsismate @nielsdos
|
||||
/ext/libxml @nielsdos
|
||||
/ext/mbstring @alexdowad @youkidearitai
|
||||
/ext/mysqli @bukka @kamil-tekiela
|
||||
|
@ -52,7 +52,6 @@
|
|||
/ext/sockets @devnexen
|
||||
/ext/spl @Girgias
|
||||
/ext/standard @bukka
|
||||
/ext/uri @kocsismate
|
||||
/ext/xml @nielsdos
|
||||
/ext/xmlreader @nielsdos
|
||||
/ext/xmlwriter @nielsdos
|
||||
|
|
16
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
16
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
@ -22,23 +22,15 @@ body:
|
|||
```
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
- type: input
|
||||
attributes:
|
||||
label: PHP Version
|
||||
description: |
|
||||
Please run PHP with the `-v` flag (e.g. `php -v`, `php8.3 -v`, `php-fpm -v` or similar) and provide the full output of that command. If executing that command is not possible, please provide the full version number as given in PHPInfo.
|
||||
|
||||
Please make sure that the used PHP version [is a supported version](https://www.php.net/supported-versions.php).
|
||||
placeholder: |
|
||||
PHP 8.3.19 (cli) (built: Mar 13 2025 17:44:40) (NTS)
|
||||
Copyright (c) The PHP Group
|
||||
Zend Engine v4.3.19, Copyright (c) Zend Technologies
|
||||
with Zend OPcache v8.3.19, Copyright (c), by Zend Technologies
|
||||
render: plain
|
||||
description: "The used PHP version. Make sure it is [supported](https://www.php.net/supported-versions.php)."
|
||||
placeholder: "PHP 8.0.12"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Operating System
|
||||
description: "The used operating system, if relevant."
|
||||
placeholder: "Ubuntu 24.04"
|
||||
placeholder: "Ubuntu 20.04"
|
||||
|
|
3
.github/ISSUE_TEMPLATE/config.yml
vendored
3
.github/ISSUE_TEMPLATE/config.yml
vendored
|
@ -3,3 +3,6 @@ contact_links:
|
|||
- name: Documentation issue
|
||||
url: https://github.com/php/doc-en/issues
|
||||
about: Please report documentation issues on the doc-en repository.
|
||||
- name: Security issue
|
||||
url: https://bugs.php.net/report.php?security_bug
|
||||
about: Please report security issues in this private bug tracker.
|
||||
|
|
59
.github/actions/apk/action.yml
vendored
59
.github/actions/apk/action.yml
vendored
|
@ -1,59 +0,0 @@
|
|||
name: apk
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- shell: sh
|
||||
run: |
|
||||
set -x
|
||||
|
||||
OPCACHE_TLS_TESTS_DEPS="clang gcc binutils-gold lld"
|
||||
|
||||
apk update -q
|
||||
apk add \
|
||||
util-linux \
|
||||
bash \
|
||||
sudo \
|
||||
build-base \
|
||||
autoconf \
|
||||
unzip \
|
||||
tar \
|
||||
bison \
|
||||
re2c \
|
||||
pkgconf \
|
||||
mysql-client \
|
||||
bzip2-dev \
|
||||
curl-dev \
|
||||
freetype-dev \
|
||||
gettext-dev \
|
||||
gnu-libiconv-dev \
|
||||
gmp-dev \
|
||||
icu-dev \
|
||||
icu-data-full \
|
||||
jpeg-dev \
|
||||
libffi-dev \
|
||||
libpng-dev \
|
||||
libsodium-dev \
|
||||
libwebp-dev \
|
||||
libxml2-dev \
|
||||
libxpm-dev \
|
||||
libxslt-dev \
|
||||
libzip-dev \
|
||||
oniguruma-dev \
|
||||
openssl-dev \
|
||||
readline-dev \
|
||||
sqlite-dev \
|
||||
tidyhtml-dev \
|
||||
gdbm-dev \
|
||||
lmdb-dev \
|
||||
argon2-dev \
|
||||
enchant2-dev \
|
||||
freetds-dev \
|
||||
imap-dev \
|
||||
net-snmp-dev \
|
||||
openldap-dev \
|
||||
unixodbc-dev \
|
||||
postgresql14-dev \
|
||||
tzdata \
|
||||
musl-locales \
|
||||
musl-locales-lang \
|
||||
$OPCACHE_TLS_TESTS_DEPS
|
13
.github/actions/apt-x32/action.yml
vendored
13
.github/actions/apt-x32/action.yml
vendored
|
@ -6,8 +6,6 @@ runs:
|
|||
run: |
|
||||
set -x
|
||||
|
||||
OPCACHE_TLS_TESTS_DEPS="gcc clang lld"
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
dpkg --add-architecture i386
|
||||
apt-get update -y | true
|
||||
|
@ -19,32 +17,37 @@ runs:
|
|||
g++-multilib \
|
||||
gcc-multilib \
|
||||
language-pack-de \
|
||||
libaspell-dev:i386 \
|
||||
libbz2-dev:i386 \
|
||||
libc6:i386 \
|
||||
libcurl4-openssl-dev:i386 \
|
||||
libffi-dev:i386 \
|
||||
libfreetype6-dev:i386 \
|
||||
libgmp-dev:i386 \
|
||||
libgssapi-krb5-2:i386 \
|
||||
libicu-dev:i386 \
|
||||
libjpeg-dev:i386 \
|
||||
libkrb5-dev:i386 \
|
||||
libonig-dev:i386 \
|
||||
libpng-dev:i386 \
|
||||
libpq-dev:i386 \
|
||||
libpspell-dev:i386 \
|
||||
libreadline-dev:i386 \
|
||||
libsasl2-dev:i386 \
|
||||
libsodium-dev:i386 \
|
||||
libsqlite3-dev:i386 \
|
||||
libssl-dev:i386 \
|
||||
libtidy-dev:i386 \
|
||||
libwebp-dev:i386 \
|
||||
libxml2-dev:i386 \
|
||||
libxml2-dev:i386 \
|
||||
libxpm-dev:i386 \
|
||||
libxslt1-dev:i386 \
|
||||
firebird-dev:i386 \
|
||||
libzip-dev:i386 \
|
||||
locales \
|
||||
make \
|
||||
pkg-config:i386 \
|
||||
re2c \
|
||||
unzip \
|
||||
wget \
|
||||
zlib1g-dev:i386 \
|
||||
$OPCACHE_TLS_TESTS_DEPS
|
||||
zlib1g-dev:i386
|
||||
|
|
18
.github/actions/apt-x64/action.yml
vendored
18
.github/actions/apt-x64/action.yml
vendored
|
@ -1,8 +1,4 @@
|
|||
name: apt
|
||||
inputs:
|
||||
asan:
|
||||
default: false
|
||||
required: false
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
|
@ -10,8 +6,6 @@ runs:
|
|||
run: |
|
||||
set -x
|
||||
|
||||
OPCACHE_TLS_TESTS_DEPS="gcc clang lld"
|
||||
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Install sudo in Docker for consistent actions
|
||||
|
@ -38,20 +32,22 @@ runs:
|
|||
libicu-dev \
|
||||
libtidy-dev \
|
||||
libenchant-2-dev \
|
||||
libaspell-dev \
|
||||
libbz2-dev \
|
||||
libpspell-dev \
|
||||
libsasl2-dev \
|
||||
libxpm-dev \
|
||||
libzip-dev \
|
||||
libsqlite3-dev \
|
||||
libsqlite3-mod-spatialite \
|
||||
libwebp-dev \
|
||||
${{ inputs.asan == 'false' && 'libavif-dev' || '' }} \
|
||||
libonig-dev \
|
||||
libkrb5-dev \
|
||||
libgssapi-krb5-2 \
|
||||
libcurl4-openssl-dev \
|
||||
libxml2-dev \
|
||||
libxslt1-dev \
|
||||
libpq-dev \
|
||||
libedit-dev \
|
||||
libreadline-dev \
|
||||
libldap2-dev \
|
||||
libsodium-dev \
|
||||
libargon2-dev \
|
||||
|
@ -65,6 +61,7 @@ runs:
|
|||
unixodbc-dev \
|
||||
llvm \
|
||||
clang \
|
||||
libc-client-dev \
|
||||
dovecot-core \
|
||||
dovecot-pop3d \
|
||||
dovecot-imapd \
|
||||
|
@ -76,5 +73,4 @@ runs:
|
|||
libqdbm-dev \
|
||||
libjpeg-dev \
|
||||
libpng-dev \
|
||||
libfreetype6-dev \
|
||||
$OPCACHE_TLS_TESTS_DEPS
|
||||
libfreetype6-dev
|
||||
|
|
4
.github/actions/brew/action.yml
vendored
4
.github/actions/brew/action.yml
vendored
|
@ -11,9 +11,6 @@ runs:
|
|||
code=" keg.link\(verbose: verbose\?"
|
||||
sudo sed -Ei '' "s/$code.*/$code, overwrite: true\)/" "$formula_installer"
|
||||
|
||||
# Some packages exist on x86 but not arm, or vice versa.
|
||||
# Install them with reinstall to avoid warnings.
|
||||
brew reinstall autoconf webp tidy-html5 libzip libsodium icu4c curl
|
||||
brew install \
|
||||
bison \
|
||||
re2c
|
||||
|
@ -22,6 +19,7 @@ runs:
|
|||
enchant \
|
||||
libffi \
|
||||
intltool \
|
||||
icu4c \
|
||||
libiconv \
|
||||
t1lib \
|
||||
libxml2 \
|
||||
|
|
79
.github/actions/configure-alpine/action.yml
vendored
79
.github/actions/configure-alpine/action.yml
vendored
|
@ -1,79 +0,0 @@
|
|||
name: ./configure
|
||||
inputs:
|
||||
configurationParameters:
|
||||
default: ''
|
||||
required: false
|
||||
skipSlow:
|
||||
default: false
|
||||
required: false
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- shell: bash
|
||||
run: |
|
||||
set -x
|
||||
./buildconf --force
|
||||
./configure \
|
||||
--enable-option-checking=fatal \
|
||||
--prefix=/usr \
|
||||
--enable-phpdbg \
|
||||
--enable-fpm \
|
||||
--with-pdo-mysql=mysqlnd \
|
||||
--with-mysqli=mysqlnd \
|
||||
${{ inputs.skipSlow == 'false' && '--with-pgsql' || '' }} \
|
||||
${{ inputs.skipSlow == 'false' && '--with-pdo-pgsql' || '' }} \
|
||||
${{ inputs.skipSlow == 'false' && '--with-pdo-sqlite' || '' }} \
|
||||
--enable-intl \
|
||||
--without-pear \
|
||||
--enable-gd \
|
||||
--with-jpeg \
|
||||
--with-webp \
|
||||
--with-freetype \
|
||||
--with-xpm \
|
||||
--enable-exif \
|
||||
--with-zip \
|
||||
--with-zlib \
|
||||
--enable-soap \
|
||||
--enable-xmlreader \
|
||||
--with-xsl \
|
||||
${{ inputs.skipSlow == 'false' && '--with-tidy' || '' }} \
|
||||
--enable-sysvsem \
|
||||
--enable-sysvshm \
|
||||
--enable-shmop \
|
||||
--enable-pcntl \
|
||||
--with-readline \
|
||||
--enable-mbstring \
|
||||
--with-iconv=/usr \
|
||||
--with-curl \
|
||||
--with-gettext \
|
||||
--enable-sockets \
|
||||
--with-bz2 \
|
||||
--with-openssl \
|
||||
--with-gmp \
|
||||
--enable-bcmath \
|
||||
--enable-calendar \
|
||||
--enable-ftp \
|
||||
${{ inputs.skipSlow == 'false' && '--with-enchant=/usr' || '' }} \
|
||||
--enable-sysvmsg \
|
||||
--with-ffi \
|
||||
--enable-zend-test \
|
||||
${{ inputs.skipSlow == 'false' && '--enable-dl-test=shared' || '' }} \
|
||||
${{ inputs.skipSlow == 'false' && '--with-ldap' || '' }} \
|
||||
${{ inputs.skipSlow == 'false' && '--with-ldap-sasl' || '' }} \
|
||||
--with-password-argon2 \
|
||||
--with-mhash \
|
||||
--with-sodium \
|
||||
--enable-dba \
|
||||
--with-cdb \
|
||||
--enable-flatfile \
|
||||
--enable-inifile \
|
||||
--with-lmdb \
|
||||
--with-gdbm \
|
||||
${{ inputs.skipSlow == 'false' && '--with-snmp' || '' }} \
|
||||
${{ inputs.skipSlow == 'false' && '--with-unixODBC' || '' }} \
|
||||
${{ inputs.skipSlow == 'false' && '--with-pdo-odbc=unixODBC,/usr' || '' }} \
|
||||
--with-config-file-path=/etc \
|
||||
--with-config-file-scan-dir=/etc/php.d \
|
||||
${{ inputs.skipSlow == 'false' && '--with-pdo-dblib' || '' }} \
|
||||
--enable-werror \
|
||||
${{ inputs.configurationParameters }}
|
36
.github/actions/configure-macos/action.yml
vendored
36
.github/actions/configure-macos/action.yml
vendored
|
@ -10,24 +10,26 @@ runs:
|
|||
run: |
|
||||
set -x
|
||||
BREW_OPT="$(brew --prefix)"/opt
|
||||
export PATH="$BREW_OPT/bison/bin:$PATH"
|
||||
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$BREW_OPT/openssl@1.1/lib/pkgconfig"
|
||||
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$BREW_OPT/curl/lib/pkgconfig"
|
||||
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$BREW_OPT/libffi/lib/pkgconfig"
|
||||
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$BREW_OPT/libxml2/lib/pkgconfig"
|
||||
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$BREW_OPT/libxslt/lib/pkgconfig"
|
||||
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$BREW_OPT/zlib/lib/pkgconfig"
|
||||
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$BREW_OPT/icu4c/lib/pkgconfig"
|
||||
export PATH="/usr/local/opt/bison/bin:$PATH"
|
||||
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/openssl@1.1/lib/pkgconfig"
|
||||
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/curl/lib/pkgconfig"
|
||||
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/krb5/lib/pkgconfig"
|
||||
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/libffi/lib/pkgconfig"
|
||||
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/libxml2/lib/pkgconfig"
|
||||
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/libxslt/lib/pkgconfig"
|
||||
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/zlib/lib/pkgconfig"
|
||||
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/icu4c/lib/pkgconfig"
|
||||
sed -i -e 's/Requires.private:.*//g' "$BREW_OPT/curl/lib/pkgconfig/libcurl.pc"
|
||||
./buildconf --force
|
||||
./configure \
|
||||
CFLAGS="-Wno-strict-prototypes -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion" \
|
||||
--enable-option-checking=fatal \
|
||||
--prefix=/usr/local \
|
||||
--enable-fpm \
|
||||
--with-pdo-mysql=mysqlnd \
|
||||
--with-mysqli=mysqlnd \
|
||||
--with-pgsql="$BREW_OPT"/libpq \
|
||||
--with-pdo-pgsql="$BREW_OPT"/libpq \
|
||||
--with-pgsql=/usr/local/opt/libpq \
|
||||
--with-pdo-pgsql=/usr/local/opt/libpq \
|
||||
--with-pdo-sqlite \
|
||||
--without-pear \
|
||||
--enable-gd \
|
||||
|
@ -40,24 +42,26 @@ runs:
|
|||
--enable-soap \
|
||||
--enable-xmlreader \
|
||||
--with-xsl \
|
||||
--with-tidy="$BREW_OPT"/tidy-html5 \
|
||||
--with-tidy=/usr/local/opt/tidy-html5 \
|
||||
--with-libxml \
|
||||
--enable-sysvsem \
|
||||
--enable-sysvshm \
|
||||
--enable-shmop \
|
||||
--enable-pcntl \
|
||||
--with-readline="$BREW_OPT"/readline \
|
||||
--with-readline=/usr/local/opt/readline \
|
||||
--enable-mbstring \
|
||||
--with-curl \
|
||||
--with-gettext="$BREW_OPT"/gettext \
|
||||
--with-gettext=/usr/local/opt/gettext \
|
||||
--enable-sockets \
|
||||
--with-bz2="$BREW_OPT"/bzip2 \
|
||||
--with-bz2=/usr/local/opt/bzip2 \
|
||||
--with-openssl \
|
||||
--with-gmp="$BREW_OPT"/gmp \
|
||||
--with-iconv="$BREW_OPT"/libiconv \
|
||||
--with-gmp=/usr/local/opt/gmp \
|
||||
--with-iconv=/usr/local/opt/libiconv \
|
||||
--enable-bcmath \
|
||||
--enable-calendar \
|
||||
--enable-ftp \
|
||||
--with-pspell=/usr/local/opt/aspell \
|
||||
--with-kerberos \
|
||||
--enable-sysvmsg \
|
||||
--with-ffi \
|
||||
--enable-zend-test \
|
||||
|
|
7
.github/actions/configure-x32/action.yml
vendored
7
.github/actions/configure-x32/action.yml
vendored
|
@ -10,7 +10,6 @@ runs:
|
|||
run: |
|
||||
set -x
|
||||
|
||||
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/i386-linux-gnu/pkgconfig"
|
||||
./buildconf --force
|
||||
export CFLAGS="-m32 -msse2"
|
||||
export CXXFLAGS="-m32 -msse2"
|
||||
|
@ -27,7 +26,6 @@ runs:
|
|||
--with-pgsql \
|
||||
--with-pdo-pgsql \
|
||||
--with-pdo-sqlite \
|
||||
--with-pdo-firebird \
|
||||
--without-pear \
|
||||
--enable-gd \
|
||||
--with-jpeg \
|
||||
|
@ -35,10 +33,13 @@ runs:
|
|||
--with-freetype \
|
||||
--with-xpm \
|
||||
--enable-exif \
|
||||
--with-zip \
|
||||
--with-zlib \
|
||||
--with-zlib-dir=/usr \
|
||||
--enable-soap \
|
||||
--enable-xmlreader \
|
||||
--with-xsl \
|
||||
--with-tidy \
|
||||
--enable-sysvsem \
|
||||
--enable-sysvshm \
|
||||
--enable-shmop \
|
||||
|
@ -54,6 +55,8 @@ runs:
|
|||
--enable-bcmath \
|
||||
--enable-calendar \
|
||||
--enable-ftp \
|
||||
--with-pspell=/usr \
|
||||
--with-kerberos \
|
||||
--enable-sysvmsg \
|
||||
--with-ffi \
|
||||
--enable-zend-test \
|
||||
|
|
10
.github/actions/configure-x64/action.yml
vendored
10
.github/actions/configure-x64/action.yml
vendored
|
@ -31,12 +31,12 @@ runs:
|
|||
--enable-gd \
|
||||
--with-jpeg \
|
||||
--with-webp \
|
||||
${{ inputs.asan == 'false' && '--with-avif' || '' }} \
|
||||
--with-freetype \
|
||||
--with-xpm \
|
||||
--enable-exif \
|
||||
--with-zip \
|
||||
--with-zlib \
|
||||
--with-zlib-dir=/usr \
|
||||
--enable-soap \
|
||||
--enable-xmlreader \
|
||||
--with-xsl \
|
||||
|
@ -45,7 +45,7 @@ runs:
|
|||
--enable-sysvshm \
|
||||
--enable-shmop \
|
||||
--enable-pcntl \
|
||||
--without-readline --with-libedit \
|
||||
--with-readline \
|
||||
--enable-mbstring \
|
||||
--with-curl \
|
||||
--with-gettext \
|
||||
|
@ -56,7 +56,9 @@ runs:
|
|||
--enable-bcmath \
|
||||
--enable-calendar \
|
||||
--enable-ftp \
|
||||
--with-pspell=/usr \
|
||||
${{ inputs.skipSlow == 'false' && '--with-enchant=/usr' || '' }} \
|
||||
--with-kerberos \
|
||||
--enable-sysvmsg \
|
||||
--with-ffi \
|
||||
--enable-zend-test \
|
||||
|
@ -75,7 +77,11 @@ runs:
|
|||
--with-qdbm \
|
||||
${{ inputs.skipSlow == 'false' && '--with-snmp' || '' }} \
|
||||
${{ inputs.skipSlow == 'false' && '--with-unixODBC' || '' }} \
|
||||
${{ inputs.skipSlow == 'false' && '--with-imap' || '' }} \
|
||||
${{ inputs.skipSlow == 'false' && '--with-imap-ssl' || '' }} \
|
||||
${{ inputs.skipSlow == 'false' && '--with-pdo-odbc=unixODBC,/usr' || '' }} \
|
||||
$([ -d "/opt/oracle/instantclient" ] && echo '--with-pdo-oci=shared,instantclient,/opt/oracle/instantclient') \
|
||||
$([ -d "/opt/oracle/instantclient" ] && echo '--with-oci8=shared,instantclient,/opt/oracle/instantclient') \
|
||||
--with-config-file-path=/etc \
|
||||
--with-config-file-scan-dir=/etc/php.d \
|
||||
${{ inputs.skipSlow == 'false' && '--with-pdo-firebird' || '' }} \
|
||||
|
|
7
.github/actions/extra-tests/action.yml
vendored
7
.github/actions/extra-tests/action.yml
vendored
|
@ -1,7 +0,0 @@
|
|||
name: Extra tests
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- shell: sh
|
||||
run: |
|
||||
sapi/cli/php run-extra-tests.php
|
19
.github/actions/freebsd/action.yml
vendored
19
.github/actions/freebsd/action.yml
vendored
|
@ -3,16 +3,13 @@ inputs:
|
|||
configurationParameters:
|
||||
default: ''
|
||||
required: false
|
||||
runExtraTests:
|
||||
default: false
|
||||
required: false
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: FreeBSD
|
||||
uses: vmactions/freebsd-vm@v1
|
||||
with:
|
||||
release: '13.5'
|
||||
release: '13.3'
|
||||
usesh: true
|
||||
copyback: false
|
||||
# Temporarily disable sqlite, as FreeBSD ships it with disabled double quotes. We'll need to fix our tests.
|
||||
|
@ -20,8 +17,6 @@ runs:
|
|||
prepare: |
|
||||
cd $GITHUB_WORKSPACE
|
||||
|
||||
OPCACHE_TLS_TESTS_DEPS="gcc"
|
||||
|
||||
kldload accf_http
|
||||
pkg install -y \
|
||||
autoconf \
|
||||
|
@ -46,11 +41,9 @@ runs:
|
|||
webp \
|
||||
libavif \
|
||||
`#sqlite3` \
|
||||
curl \
|
||||
$OPCACHE_TLS_TESTS_DEPS
|
||||
curl
|
||||
|
||||
./buildconf -f
|
||||
CC=clang CXX=clang++ \
|
||||
./configure \
|
||||
--prefix=/usr/local \
|
||||
--enable-debug \
|
||||
|
@ -89,7 +82,6 @@ runs:
|
|||
--enable-intl \
|
||||
--with-mhash \
|
||||
--with-sodium \
|
||||
--enable-werror \
|
||||
--with-config-file-path=/etc \
|
||||
--with-config-file-scan-dir=/etc/php.d \
|
||||
${{ inputs.configurationParameters }}
|
||||
|
@ -113,8 +105,5 @@ runs:
|
|||
--offline \
|
||||
--show-diff \
|
||||
--show-slow 1000 \
|
||||
--set-timeout 120
|
||||
|
||||
if test "${{ inputs.runExtraTests }}" = "true"; then
|
||||
sapi/cli/php run-extra-tests.php
|
||||
fi
|
||||
--set-timeout 120 \
|
||||
-d zend_extension=opcache.so
|
||||
|
|
10
.github/actions/install-alpine/action.yml
vendored
10
.github/actions/install-alpine/action.yml
vendored
|
@ -1,10 +0,0 @@
|
|||
name: Install
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- shell: bash
|
||||
run: |
|
||||
set -x
|
||||
sudo make install
|
||||
sudo mkdir -p /etc/php.d
|
||||
sudo chmod 777 /etc/php.d
|
30
.github/actions/setup-oracle/action.yml
vendored
Normal file
30
.github/actions/setup-oracle/action.yml
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
name: Create Oracle container
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- shell: bash
|
||||
run: |
|
||||
set -x
|
||||
docker run \
|
||||
-e "ORACLE_PASSWORD=pass" \
|
||||
-p 1521:1521 \
|
||||
--name oracle \
|
||||
-h oracle \
|
||||
-d gvenzl/oracle-xe:slim
|
||||
|
||||
mkdir /opt/oracle
|
||||
wget -nv https://download.oracle.com/otn_software/linux/instantclient/2114000/instantclient-basiclite-linux.x64-21.14.0.0.0dbru.zip
|
||||
unzip instantclient-basiclite-linux.x64-21.14.0.0.0dbru.zip && rm instantclient-basiclite-linux.x64-21.14.0.0.0dbru.zip
|
||||
wget -nv https://download.oracle.com/otn_software/linux/instantclient/2114000/instantclient-sdk-linux.x64-21.14.0.0.0dbru.zip
|
||||
unzip instantclient-sdk-linux.x64-21.14.0.0.0dbru.zip && rm instantclient-sdk-linux.x64-21.14.0.0.0dbru.zip
|
||||
mv instantclient_*_* /opt/oracle/instantclient
|
||||
# interferes with libldap2 headers
|
||||
rm /opt/oracle/instantclient/sdk/include/ldap.h
|
||||
# fix debug build warning: zend_signal: handler was replaced for signal (2) after startup
|
||||
echo DISABLE_INTERRUPT=on > /opt/oracle/instantclient/network/admin/sqlnet.ora
|
||||
sudo sh -c 'echo /opt/oracle/instantclient >/etc/ld.so.conf.d/oracle-instantclient.conf && ldconfig'
|
||||
|
||||
sudo mkdir -p /etc/php.d
|
||||
sudo chmod 777 /etc/php.d
|
||||
echo extension=oci8.so > /etc/php.d/oci8.ini
|
||||
echo extension=pdo_oci.so > /etc/php.d/pdo_oci.ini
|
6
.github/actions/setup-x64/action.yml
vendored
6
.github/actions/setup-x64/action.yml
vendored
|
@ -19,3 +19,9 @@ runs:
|
|||
sudo cp ext/snmp/tests/snmpd.conf /etc/snmp
|
||||
sudo cp ext/snmp/tests/bigtest /etc/snmp
|
||||
sudo service snmpd restart
|
||||
|
||||
sudo groupadd -g 5000 vmail
|
||||
sudo useradd -m -d /var/vmail -s /bin/false -u 5000 -g vmail vmail
|
||||
sudo cp ext/imap/tests/setup/dovecot.conf /etc/dovecot/dovecot.conf
|
||||
sudo cp ext/imap/tests/setup/dovecotpass /etc/dovecot/dovecotpass
|
||||
sudo service dovecot restart
|
||||
|
|
25
.github/actions/test-alpine/action.yml
vendored
25
.github/actions/test-alpine/action.yml
vendored
|
@ -1,25 +0,0 @@
|
|||
name: Test
|
||||
inputs:
|
||||
runTestsParameters:
|
||||
default: ''
|
||||
required: false
|
||||
jitType:
|
||||
default: 'disable'
|
||||
required: false
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- shell: bash
|
||||
run: |
|
||||
set -x
|
||||
export SKIP_IO_CAPTURE_TESTS=1
|
||||
export STACK_LIMIT_DEFAULTS_CHECK=1
|
||||
sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \
|
||||
-d opcache.jit=${{ inputs.jitType }} \
|
||||
-d opcache.jit_buffer_size=64M \
|
||||
-j$(nproc) \
|
||||
-g FAIL,BORK,LEAK,XLEAK \
|
||||
--no-progress \
|
||||
--show-diff \
|
||||
--show-slow 1000 \
|
||||
--set-timeout 120
|
15
.github/actions/test-linux/action.yml
vendored
15
.github/actions/test-linux/action.yml
vendored
|
@ -25,16 +25,16 @@ runs:
|
|||
export PDO_DBLIB_TEST_DSN="dblib:host=127.0.0.1;dbname=master;version=7.0"
|
||||
export PDO_DBLIB_TEST_USER="pdo_test"
|
||||
export PDO_DBLIB_TEST_PASS="password"
|
||||
export PHP_OCI8_TEST_USER="system"
|
||||
export PHP_OCI8_TEST_PASS="pass"
|
||||
export PHP_OCI8_TEST_DB="localhost/XEPDB1"
|
||||
export PDO_OCI_TEST_USER="system"
|
||||
export PDO_OCI_TEST_PASS="pass"
|
||||
export PDO_OCI_TEST_DSN="oci:dbname=localhost/XEPDB1;charset=AL32UTF8"
|
||||
export PGSQL_TEST_CONNSTR="host=localhost dbname=test port=5432 user=postgres password=postgres"
|
||||
if [[ -z "$PDO_PGSQL_TEST_DSN" ]]; then
|
||||
export PDO_PGSQL_TEST_DSN="pgsql:host=localhost port=5432 dbname=test user=postgres password=postgres"
|
||||
fi
|
||||
export PDO_FIREBIRD_TEST_DATABASE=test.fdb
|
||||
if [[ -z "$PDO_FIREBIRD_TEST_DSN" ]]; then
|
||||
export PDO_FIREBIRD_TEST_DSN=firebird:dbname=localhost:test.fdb
|
||||
fi
|
||||
export PDO_FIREBIRD_TEST_PASS=test
|
||||
export PDO_FIREBIRD_TEST_USER=test
|
||||
export ODBC_TEST_USER="odbc_test"
|
||||
export ODBC_TEST_PASS="password"
|
||||
export ODBC_TEST_DSN="Driver={ODBC Driver 17 for SQL Server};Server=127.0.0.1;Database=odbc;uid=$ODBC_TEST_USER;pwd=$ODBC_TEST_PASS"
|
||||
|
@ -43,8 +43,7 @@ runs:
|
|||
export STACK_LIMIT_DEFAULTS_CHECK=1
|
||||
sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \
|
||||
-d opcache.jit=${{ inputs.jitType }} \
|
||||
-d opcache.protect_memory=1 \
|
||||
-d opcache.jit_buffer_size=64M \
|
||||
-d opcache.jit_buffer_size=16M \
|
||||
${{ inputs.idleCpu == 'true' && '-j$(($(/usr/bin/nproc) - 1))' || '-j$(/usr/bin/nproc)' }} \
|
||||
-g FAIL,BORK,LEAK,XLEAK \
|
||||
--no-progress \
|
||||
|
|
3
.github/actions/test-macos/action.yml
vendored
3
.github/actions/test-macos/action.yml
vendored
|
@ -17,8 +17,7 @@ runs:
|
|||
export STACK_LIMIT_DEFAULTS_CHECK=1
|
||||
sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \
|
||||
-d opcache.jit=${{ inputs.jitType }} \
|
||||
-d opcache.protect_memory=1 \
|
||||
-d opcache.jit_buffer_size=64M \
|
||||
-d opcache.jit_buffer_size=16M \
|
||||
-j$(($(sysctl -n hw.ncpu) - 1)) \
|
||||
-g FAIL,BORK,LEAK,XLEAK \
|
||||
--no-progress \
|
||||
|
|
|
@ -4,13 +4,13 @@ runs:
|
|||
steps:
|
||||
- shell: bash
|
||||
run: |
|
||||
set -ex
|
||||
[[ "$OSTYPE" == "darwin"* ]] && export PATH="$(brew --prefix)/opt/bison/bin:$PATH"
|
||||
set -x
|
||||
[[ "$OSTYPE" == "darwin"* ]] && export PATH="/usr/local/opt/bison/bin:$PATH"
|
||||
scripts/dev/credits
|
||||
scripts/dev/genfiles
|
||||
scripts/gdb/debug_gdb_scripts_gen.php
|
||||
Zend/zend_vm_gen.php
|
||||
ext/tokenizer/tokenizer_data_gen.php
|
||||
build/gen_stub.php -f --generate-optimizer-info --verify
|
||||
build/gen_stub.php -f
|
||||
build/gen_stub.php --generate-optimizer-info
|
||||
# Use the -a flag for a bug in git 2.46.0, which doesn't consider changed -diff files.
|
||||
git add . -N && git diff -a --exit-code
|
||||
|
|
201
.github/labeler.yml
vendored
201
.github/labeler.yml
vendored
|
@ -1,16 +1,10 @@
|
|||
"Category: Engine":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- Zend/*
|
||||
|
||||
"Category: Optimizer":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- Zend/Optimizer/**/*
|
||||
|
||||
"Category: Build System":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- '**/*.m4'
|
||||
- '**/*.w32'
|
||||
- build/**/*
|
||||
|
@ -21,413 +15,258 @@
|
|||
- win32/build/**/*
|
||||
|
||||
"Extension: bcmath":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/bcmath/**/*
|
||||
|
||||
"Extension: bz2":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/bz2/**/*
|
||||
|
||||
"Extension: calendar":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/calendar/**/*
|
||||
|
||||
"Extension: com_dotnet":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/com_dotnet/**/*
|
||||
|
||||
"Extension: ctype":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/ctype/**/*
|
||||
|
||||
"Extension: curl":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/curl/**/*
|
||||
|
||||
"Extension: date":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/date/**/*
|
||||
|
||||
"Extension: dba":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/dba/**/*
|
||||
|
||||
"Extension: dom":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/dom/**/*
|
||||
|
||||
"Extension: enchant":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/enchant/**/*
|
||||
|
||||
"Extension: exif":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/exif/**/*
|
||||
|
||||
"Extension: ffi":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/ffi/**/*
|
||||
|
||||
"Extension: fileinfo":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/fileinfo/**/*
|
||||
|
||||
"Extension: filter":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/filter/**/*
|
||||
|
||||
"Extension: ftp":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/ftp/**/*
|
||||
|
||||
"Extension: gd":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/gd/**/*
|
||||
|
||||
"Extension: gettext":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/gettext/**/*
|
||||
|
||||
"Extension: gmp":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/gmp/**/*
|
||||
|
||||
"Extension: hash":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/hash/**/*
|
||||
|
||||
"Extension: iconv":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/iconv/**/*
|
||||
|
||||
"Extension: imap":
|
||||
- ext/imap/**/*
|
||||
|
||||
"Extension: intl":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/intl/**/*
|
||||
|
||||
"Extension: json":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/json/**/*
|
||||
|
||||
"Extension: ldap":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/ldap/**/*
|
||||
|
||||
"Extension: libxml":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/libxml/**/*
|
||||
|
||||
"Extension: mbstring":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/mbstring/**/*
|
||||
|
||||
"Extension: mysqli":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/mysqli/**/*
|
||||
|
||||
"Extension: mysqlnd":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/mysqlnd/**/*
|
||||
|
||||
"Extension: oci8":
|
||||
- ext/oci8/**/*
|
||||
|
||||
"Extension: odbc":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/odbc/**/*
|
||||
|
||||
"Extension: opcache":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/opcache/**/*
|
||||
|
||||
"Extension: openssl":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/openssl/**/*
|
||||
|
||||
"Extension: pcntl":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/pcntl/**/*
|
||||
|
||||
"Extension: pcre":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/pcre/**/*
|
||||
|
||||
"Extension: pdo (core)":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/pdo/**/*
|
||||
|
||||
"Extension: pdo_dblib":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/pdo_dblib/**/*
|
||||
|
||||
"Extension: pdo_firebird":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/pdo_firebird/**/*
|
||||
|
||||
"Extension: pdo_mysql":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/pdo_mysql/**/*
|
||||
|
||||
"Extension: pdo_oci":
|
||||
- ext/pdo_oci/**/*
|
||||
|
||||
"Extension: pdo_odbc":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/pdo_odbc/**/*
|
||||
|
||||
"Extension: pdo_pgsql":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/pdo_pgsql/**/*
|
||||
|
||||
"Extension: pdo_sqlite":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/pdo_sqlite/**/*
|
||||
|
||||
"Extension: pgsql":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/pgsql/**/*
|
||||
|
||||
"Extension: phar":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/phar/**/*
|
||||
|
||||
"Extension: posix":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/posix/**/*
|
||||
|
||||
"Extension: pspell":
|
||||
- ext/pspell/**/*
|
||||
|
||||
"Extension: random":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/random/**/*
|
||||
|
||||
"Extension: readline":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/readline/**/*
|
||||
|
||||
"Extension: reflection":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/reflection/**/*
|
||||
|
||||
"Extension: session":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/session/**/*
|
||||
|
||||
"Extension: shmop":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/shmop/**/*
|
||||
|
||||
"Extension: simplexml":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/simplexml/**/*
|
||||
|
||||
"Extension: snmp":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/snmp/**/*
|
||||
|
||||
"Extension: soap":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/soap/**/*
|
||||
|
||||
"Extension: sockets":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/sockets/**/*
|
||||
|
||||
"Extension: sodium":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/sodium/**/*
|
||||
|
||||
"Extension: spl":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/spl/**/*
|
||||
|
||||
"Extension: sqlite3":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/sqlite3/**/*
|
||||
|
||||
"Extension: standard":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/standard/**/*
|
||||
|
||||
"Extension: sysvmsg":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/sysvmsg/**/*
|
||||
|
||||
"Extension: sysvsem":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/sysvsem/**/*
|
||||
|
||||
"Extension: sysvshm":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/sysvshm/**/*
|
||||
|
||||
"Extension: tidy":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/tidy/**/*
|
||||
|
||||
"Extension: tokenizer":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/tokenizer/**/*
|
||||
|
||||
"Extension: uri":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/uri/**/*
|
||||
|
||||
"Extension: xml":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/xml/**/*
|
||||
|
||||
"Extension: xmlreader":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/xmlreader/**/*
|
||||
|
||||
"Extension: xmlwriter":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/xmlwriter/**/*
|
||||
|
||||
"Extension: xsl":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/xsl/**/*
|
||||
|
||||
"Extension: zend_test":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/zend_test/**/*
|
||||
|
||||
"Extension: zip":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/zip/**/*
|
||||
|
||||
"Extension: zlib":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- ext/zlib/**/*
|
||||
|
||||
"SAPI: apache2handler":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- sapi/apache2handler/**/*
|
||||
|
||||
"SAPI: cgi":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- sapi/cgi/**/*
|
||||
|
||||
"SAPI: cli":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- sapi/cli/**/*
|
||||
|
||||
"SAPI: fpm":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- sapi/fpm/**/*
|
||||
|
||||
"SAPI: fuzzer":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- sapi/fuzzer/**/*
|
||||
|
||||
"SAPI: litespeed":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- sapi/litespeed/**/*
|
||||
|
||||
"SAPI: phpdbg":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- sapi/phpdbg/**/*
|
||||
|
||||
"ABI break":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- 'TSRM/*.h'
|
||||
- 'Zend/*.h'
|
||||
- 'Zend/Optimizer/zend_call_graph.h'
|
||||
- 'Zend/Optimizer/zend_cfg.h'
|
||||
- 'Zend/Optimizer/zend_dfg.h'
|
||||
- 'Zend/Optimizer/zend_dump.h'
|
||||
- 'Zend/Optimizer/zend_func_info.h'
|
||||
- 'Zend/Optimizer/zend_inference.h'
|
||||
- 'Zend/Optimizer/zend_optimizer.h'
|
||||
- 'Zend/Optimizer/zend_ssa.h'
|
||||
- 'Zend/Optimizer/zend_worklist.h'
|
||||
- 'ext/curl/php_curl.h'
|
||||
- 'ext/date/lib/timelib.h'
|
||||
- 'ext/date/lib/timelib_config.h'
|
||||
- 'ext/date/php_date.h'
|
||||
- 'ext/dom/dom_ce.h'
|
||||
- 'ext/dom/namespace_compat.h'
|
||||
- 'ext/dom/xml_common.h'
|
||||
- 'ext/dom/xpath_callbacks.h'
|
||||
- 'ext/filter/php_filter.h'
|
||||
- 'ext/gd/libgd/*.h'
|
||||
- 'ext/gd/php_gd.h'
|
||||
- 'ext/gmp/php_gmp_int.h'
|
||||
- 'ext/hash/php_hash.h'
|
||||
- 'ext/hash/php_hash_adler32.h'
|
||||
- 'ext/hash/php_hash_crc32.h'
|
||||
- 'ext/hash/php_hash_fnv.h'
|
||||
- 'ext/hash/php_hash_gost.h'
|
||||
- 'ext/hash/php_hash_haval.h'
|
||||
- 'ext/hash/php_hash_joaat.h'
|
||||
- 'ext/hash/php_hash_md.h'
|
||||
- 'ext/hash/php_hash_murmur.h'
|
||||
- 'ext/hash/php_hash_ripemd.h'
|
||||
|
@ -437,12 +276,9 @@
|
|||
- 'ext/hash/php_hash_tiger.h'
|
||||
- 'ext/hash/php_hash_whirlpool.h'
|
||||
- 'ext/hash/php_hash_xxhash.h'
|
||||
- 'ext/hash/xxhash/xxhash.h'
|
||||
- 'ext/iconv/php_iconv.h'
|
||||
- 'ext/json/php_json.h'
|
||||
- 'ext/json/php_json_parser.h'
|
||||
- 'ext/json/php_json_scanner.h'
|
||||
- 'ext/libxml/php_libxml.h'
|
||||
- 'ext/mbstring/libmbfl/config.h'
|
||||
- 'ext/mbstring/libmbfl/mbfl/eaw_table.h'
|
||||
- 'ext/mbstring/libmbfl/mbfl/mbfilter.h'
|
||||
|
@ -458,33 +294,25 @@
|
|||
- 'ext/mbstring/libmbfl/mbfl/mbfl_memory_device.h'
|
||||
- 'ext/mbstring/libmbfl/mbfl/mbfl_string.h'
|
||||
- 'ext/mbstring/mbstring.h'
|
||||
- 'ext/mbstring/php_mbregex.h'
|
||||
- 'ext/mbstring/php_onig_compat.h'
|
||||
- 'ext/mysqli/mysqli_mysqlnd.h'
|
||||
- 'ext/mysqli/php_mysqli_structs.h'
|
||||
- 'ext/mysqlnd/*.h'
|
||||
- 'ext/pcre/pcre2lib/*.h'
|
||||
- 'ext/pcre/php_pcre.h'
|
||||
- 'ext/pdo/pdo_sql_parser.h'
|
||||
- 'ext/pdo/php_pdo.h'
|
||||
- 'ext/pdo/php_pdo_driver.h'
|
||||
- 'ext/pdo/php_pdo_error.h'
|
||||
- 'ext/random/php_random.h'
|
||||
- 'ext/random/php_random_csprng.h'
|
||||
- 'ext/random/php_random_uint128.h'
|
||||
- 'ext/session/mod_files.h'
|
||||
- 'ext/session/mod_mm.h'
|
||||
- 'ext/session/mod_user.h'
|
||||
- 'ext/session/php_session.h'
|
||||
- 'ext/simplexml/php_simplexml.h'
|
||||
- 'ext/simplexml/php_simplexml_exports.h'
|
||||
- 'ext/sockets/php_sockets.h'
|
||||
- 'ext/sockets/windows_common.h'
|
||||
- 'ext/sodium/php_libsodium.h'
|
||||
- 'ext/spl/php_spl.h'
|
||||
- 'ext/spl/spl_array.h'
|
||||
- 'ext/spl/spl_directory.h'
|
||||
- 'ext/spl/spl_dllist.h'
|
||||
- 'ext/spl/spl_engine.h'
|
||||
- 'ext/spl/spl_exceptions.h'
|
||||
- 'ext/spl/spl_fixedarray.h'
|
||||
- 'ext/spl/spl_functions.h'
|
||||
|
@ -492,10 +320,7 @@
|
|||
- 'ext/spl/spl_iterators.h'
|
||||
- 'ext/spl/spl_observer.h'
|
||||
- 'ext/standard/*.h'
|
||||
- 'ext/xml/expat_compat.h'
|
||||
- 'ext/xml/php_xml.h'
|
||||
- 'main/*.h'
|
||||
- 'main/streams/*.h'
|
||||
- 'sapi/cli/cli.h'
|
||||
- 'sapi/embed/php_embed.h'
|
||||
- 'win32/*.h'
|
||||
|
|
1
.github/lsan-suppressions.txt
vendored
1
.github/lsan-suppressions.txt
vendored
|
@ -1,4 +1,3 @@
|
|||
leak:acommon::DictInfoList::elements
|
||||
leak:timer_create
|
||||
leak:netsnmp_init_mib_internals
|
||||
leak:isc_attach_database
|
||||
|
|
3
.github/scripts/setup-slapd.sh
vendored
3
.github/scripts/setup-slapd.sh
vendored
|
@ -72,9 +72,6 @@ olcTLSCertificateKeyFile: /etc/ldap/ssl/server.key
|
|||
add: olcTLSVerifyClient
|
||||
olcTLSVerifyClient: never
|
||||
-
|
||||
add: olcTLSProtocolMin
|
||||
olcTLSProtocolMin: 3.3
|
||||
-
|
||||
add: olcAuthzRegexp
|
||||
olcAuthzRegexp: uid=usera,cn=digest-md5,cn=auth cn=usera,dc=my-domain,dc=com
|
||||
-
|
||||
|
|
2
.github/scripts/windows/build.bat
vendored
2
.github/scripts/windows/build.bat
vendored
|
@ -1,3 +1,5 @@
|
|||
@echo off
|
||||
|
||||
if /i "%GITHUB_ACTIONS%" neq "True" (
|
||||
echo for CI only
|
||||
exit /b 3
|
||||
|
|
15
.github/scripts/windows/build_task.bat
vendored
15
.github/scripts/windows/build_task.bat
vendored
|
@ -25,17 +25,18 @@ if %errorlevel% neq 0 exit /b 3
|
|||
|
||||
if "%THREAD_SAFE%" equ "0" set ADD_CONF=%ADD_CONF% --disable-zts
|
||||
if "%INTRINSICS%" neq "" set ADD_CONF=%ADD_CONF% --enable-native-intrinsics=%INTRINSICS%
|
||||
if "%ASAN%" equ "1" set ADD_CONF=%ADD_CONF% --enable-sanitizer --enable-debug-pack
|
||||
|
||||
rem C4018: comparison: signed/unsigned mismatch
|
||||
rem C4146: unary minus operator applied to unsigned type
|
||||
rem C4244: type conversion, possible loss of data
|
||||
rem C4267: 'size_t' type conversion, possible loss of data
|
||||
set CFLAGS=/W3 /WX /wd4018 /wd4146 /wd4244 /wd4267
|
||||
rem Some undefined behavior is reported on 32-bit, this should be fixed
|
||||
if "%PLATFORM%" == "x86" (
|
||||
set CFLAGS=/W1
|
||||
) else (
|
||||
set CFLAGS=/W1 /WX
|
||||
)
|
||||
|
||||
cmd /c configure.bat ^
|
||||
--enable-snapshot-build ^
|
||||
--disable-debug-pack ^
|
||||
--enable-com-dotnet=shared ^
|
||||
--without-analyzer ^
|
||||
--enable-object-out-dir=%PHP_BUILD_OBJ_DIR% ^
|
||||
--with-php-build=%DEPS_DIR% ^
|
||||
|
@ -45,7 +46,5 @@ if %errorlevel% neq 0 exit /b 3
|
|||
|
||||
nmake /NOLOGO
|
||||
if %errorlevel% neq 0 exit /b 3
|
||||
nmake /NOLOGO comtest.dll
|
||||
if %errorlevel% neq 0 exit /b 3
|
||||
|
||||
exit /b 0
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
for /f "usebackq tokens=3" %%i in (`findstr PHP_MAJOR_VERSION main\php_version.h`) do set BRANCH=%%i
|
||||
for /f "usebackq tokens=3" %%i in (`findstr PHP_MINOR_VERSION main\php_version.h`) do set BRANCH=%BRANCH%.%%i
|
||||
|
||||
if /i "%BRANCH%" equ "8.5" (
|
||||
if /i "%BRANCH%" equ "8.4" (
|
||||
set BRANCH=master
|
||||
)
|
||||
|
|
2
.github/scripts/windows/test.bat
vendored
2
.github/scripts/windows/test.bat
vendored
|
@ -1,3 +1,5 @@
|
|||
@echo off
|
||||
|
||||
if /i "%GITHUB_ACTIONS%" neq "True" (
|
||||
echo for CI only
|
||||
exit /b 3
|
||||
|
|
39
.github/scripts/windows/test_task.bat
vendored
39
.github/scripts/windows/test_task.bat
vendored
|
@ -1,3 +1,5 @@
|
|||
@echo off
|
||||
|
||||
if /i "%GITHUB_ACTIONS%" neq "True" (
|
||||
echo for CI only
|
||||
exit /b 3
|
||||
|
@ -51,22 +53,19 @@ set PDOTEST_DSN=odbc:%ODBC_TEST_DSN%
|
|||
|
||||
rem setup Firebird related exts
|
||||
if "%PLATFORM%" == "x64" (
|
||||
set PHP_FIREBIRD_DOWNLOAD_URL=https://github.com/FirebirdSQL/firebird/releases/download/v4.0.4/Firebird-4.0.4.3010-0-x64.zip
|
||||
set PHP_FIREBIRD_DOWNLOAD_URL=https://github.com/FirebirdSQL/firebird/releases/download/v3.0.9/Firebird-3.0.9.33560-0_x64.zip
|
||||
) else (
|
||||
set PHP_FIREBIRD_DOWNLOAD_URL=https://github.com/FirebirdSQL/firebird/releases/download/v4.0.4/Firebird-4.0.4.3010-0-Win32.zip
|
||||
set PHP_FIREBIRD_DOWNLOAD_URL=https://github.com/FirebirdSQL/firebird/releases/download/v3.0.9/Firebird-3.0.9.33560-0_Win32.zip
|
||||
)
|
||||
curl -sLo Firebird.zip %PHP_FIREBIRD_DOWNLOAD_URL%
|
||||
7z x -oC:\Firebird Firebird.zip
|
||||
set PDO_FIREBIRD_TEST_DATABASE=C:\test.fdb
|
||||
set PDO_FIREBIRD_TEST_DSN=firebird:dbname=127.0.0.1:%PDO_FIREBIRD_TEST_DATABASE%
|
||||
set PDO_FIREBIRD_TEST_DSN=firebird:dbname=%PDO_FIREBIRD_TEST_DATABASE%
|
||||
set PDO_FIREBIRD_TEST_USER=SYSDBA
|
||||
set PDO_FIREBIRD_TEST_PASS=phpfi
|
||||
echo create user %PDO_FIREBIRD_TEST_USER% password '%PDO_FIREBIRD_TEST_PASS%';> C:\Firebird\create_user.sql
|
||||
echo commit;>> C:\Firebird\create_user.sql
|
||||
echo create database '%PDO_FIREBIRD_TEST_DATABASE%' user '%PDO_FIREBIRD_TEST_USER%' password '%PDO_FIREBIRD_TEST_PASS%';> C:\Firebird\setup.sql
|
||||
C:\Firebird\instsvc.exe install -n TestInstance
|
||||
C:\Firebird\isql -q -i C:\Firebird\setup.sql
|
||||
C:\Firebird\isql -q -i C:\Firebird\create_user.sql -user sysdba %PDO_FIREBIRD_TEST_DATABASE%
|
||||
C:\Firebird\instsvc.exe start -n TestInstance
|
||||
if %errorlevel% neq 0 exit /b 3
|
||||
path C:\Firebird;%PATH%
|
||||
|
@ -91,7 +90,9 @@ set OPENSSL_CONF=
|
|||
rem set SSLEAY_CONF=
|
||||
|
||||
rem prepare for OPcache
|
||||
if "%OPCACHE%" equ "1" set OPCACHE_OPTS=-d opcache.enable=1 -d opcache.enable_cli=1 -d opcache.protect_memory=1 -d opcache.jit_buffer_size=64M -d opcache.jit=tracing
|
||||
if "%OPCACHE%" equ "1" set OPCACHE_OPTS=-d opcache.enable=1 -d opcache.enable_cli=1 -d opcache.protect_memory=1 -d opcache.jit_buffer_size=16M
|
||||
rem work-around for failing to dl(mysqli) with OPcache (https://github.com/php/php-src/issues/8508)
|
||||
if "%OPCACHE%" equ "1" set OPCACHE_OPTS=%OPCACHE_OPTS% -d extension=mysqli
|
||||
|
||||
rem prepare for enchant
|
||||
mkdir %~d0\usr\local\lib\enchant-2
|
||||
|
@ -109,7 +110,6 @@ popd
|
|||
|
||||
rem prepare for snmp
|
||||
set MIBDIRS=%DEPS_DIR%\share\mibs
|
||||
sed -i "s/exec HexTest .*/exec HexTest cscript\.exe \/nologo %GITHUB_WORKSPACE:\=\/%\/ext\/snmp\/tests\/bigtest\.js/g" %GITHUB_WORKSPACE%\ext\snmp\tests\snmpd.conf
|
||||
start %DEPS_DIR%\bin\snmpd.exe -C -c %GITHUB_WORKSPACE%\ext\snmp\tests\snmpd.conf -Ln
|
||||
|
||||
set PHP_BUILD_DIR=%PHP_BUILD_OBJ_DIR%\Release
|
||||
|
@ -119,42 +119,37 @@ rem prepare for mail
|
|||
curl -sLo hMailServer.exe https://www.hmailserver.com/download_file/?downloadid=271
|
||||
hMailServer.exe /verysilent
|
||||
cd %APPVEYOR_BUILD_FOLDER%
|
||||
%PHP_BUILD_DIR%\php.exe -dextension_dir=%PHP_BUILD_DIR% -dextension=com_dotnet .github\setup_hmailserver.php
|
||||
|
||||
rem prepare for com_dotnet
|
||||
nmake register_comtest
|
||||
%PHP_BUILD_DIR%\php.exe -dextension_dir=%PHP_BUILD_DIR% -dextension=com_dotnet appveyor\setup_hmailserver.php
|
||||
|
||||
mkdir %PHP_BUILD_DIR%\test_file_cache
|
||||
rem generate php.ini
|
||||
echo extension_dir=%PHP_BUILD_DIR% > %PHP_BUILD_DIR%\php.ini
|
||||
echo opcache.file_cache=%PHP_BUILD_DIR%\test_file_cache >> %PHP_BUILD_DIR%\php.ini
|
||||
echo opcache.record_warnings=1 >> %PHP_BUILD_DIR%\php.ini
|
||||
if "%OPCACHE%" equ "1" echo zend_extension=php_opcache.dll >> %PHP_BUILD_DIR%\php.ini
|
||||
rem work-around for some spawned PHP processes requiring OpenSSL and sockets
|
||||
echo extension=php_openssl.dll >> %PHP_BUILD_DIR%\php.ini
|
||||
echo extension=php_sockets.dll >> %PHP_BUILD_DIR%\php.ini
|
||||
|
||||
rem remove ext dlls for which tests are not supported
|
||||
for %%i in (ldap) do (
|
||||
for %%i in (ldap oci8_12c pdo_oci) do (
|
||||
del %PHP_BUILD_DIR%\php_%%i.dll
|
||||
)
|
||||
|
||||
rem reduce excessive stack reserve for testing
|
||||
editbin /stack:8388608 %PHP_BUILD_DIR%\php.exe
|
||||
editbin /stack:8388608 %PHP_BUILD_DIR%\php-cgi.exe
|
||||
|
||||
set TEST_PHPDBG_EXECUTABLE=%PHP_BUILD_DIR%\phpdbg.exe
|
||||
|
||||
copy /-y %DEPS_DIR%\bin\*.dll %PHP_BUILD_DIR%\*
|
||||
|
||||
if "%ASAN%" equ "1" set ASAN_OPTS=--asan
|
||||
|
||||
mkdir c:\tests_tmp
|
||||
|
||||
nmake test TESTS="%OPCACHE_OPTS% -g FAIL,BORK,LEAK,XLEAK %ASAN_OPTS% --no-progress -q --offline --show-diff --show-slow 1000 --set-timeout 120 --temp-source c:\tests_tmp --temp-target c:\tests_tmp %PARALLEL%"
|
||||
nmake test TESTS="%OPCACHE_OPTS% -g FAIL,BORK,LEAK,XLEAK --no-progress -q --offline --show-diff --show-slow 1000 --set-timeout 120 --temp-source c:\tests_tmp --temp-target c:\tests_tmp --bless %PARALLEL%"
|
||||
|
||||
set EXIT_CODE=%errorlevel%
|
||||
|
||||
nmake unregister_comtest
|
||||
taskkill /f /im snmpd.exe
|
||||
|
||||
if %EXIT_CODE% GEQ 1 (
|
||||
git checkout ext\pgsql\tests\config.inc
|
||||
git diff > bless_tests.patch
|
||||
)
|
||||
|
||||
exit /b %EXIT_CODE%
|
||||
|
|
25
.github/setup_hmailserver.php
vendored
25
.github/setup_hmailserver.php
vendored
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
/** If required change these values to make the test runs */
|
||||
const IMAP_MAIL_DOMAIN = 'example.com';
|
||||
const IMAP_MAILBOX_PASSWORD = 'p4ssw0rd';
|
||||
/** Tests require 4 valid userids */
|
||||
const IMAP_USERS = ["webmaster", "info", "admin", "foo"];
|
||||
|
||||
$hmail = new COM("hMailServer.Application");
|
||||
$hmail->authenticate("Administrator", "");
|
||||
|
||||
$domain = $hmail->Domains->Add();
|
||||
$domain->Name = IMAP_MAIL_DOMAIN;
|
||||
$domain->Active = true;
|
||||
$domain->Save();
|
||||
|
||||
$accounts = $domain->accounts();
|
||||
|
||||
foreach (IMAP_USERS as $user) {
|
||||
$account = $accounts->Add();
|
||||
$account->Address = "$user@" . IMAP_MAIL_DOMAIN;
|
||||
$account->Password = IMAP_MAILBOX_PASSWORD;
|
||||
$account->Active = true;
|
||||
$account->Save();
|
||||
}
|
2
.github/workflows/close-needs-feedback.yml
vendored
2
.github/workflows/close-needs-feedback.yml
vendored
|
@ -9,7 +9,7 @@ permissions:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
if: github.repository == 'php/php-src'
|
||||
if: github.repository_owner == 'php'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
|
|
|
@ -9,13 +9,13 @@ permissions:
|
|||
|
||||
jobs:
|
||||
stale:
|
||||
if: github.repository == 'php/php-src'
|
||||
if: github.repository_owner == 'php'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
- uses: actions/stale@v6
|
||||
with:
|
||||
days-before-close: 14
|
||||
days-before-stale: 90
|
||||
|
|
4
.github/workflows/close-stale-prs.yml
vendored
4
.github/workflows/close-stale-prs.yml
vendored
|
@ -9,13 +9,13 @@ permissions:
|
|||
|
||||
jobs:
|
||||
stale:
|
||||
if: github.repository == 'php/php-src'
|
||||
if: github.repository_owner == 'php'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
- uses: actions/stale@v6
|
||||
with:
|
||||
days-before-close: 7
|
||||
days-before-stale: 60
|
||||
|
|
30
.github/workflows/docs.yml
vendored
30
.github/workflows/docs.yml
vendored
|
@ -1,30 +0,0 @@
|
|||
name: Docs
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- docs/**
|
||||
pull_request:
|
||||
paths:
|
||||
- docs/**
|
||||
jobs:
|
||||
pages:
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
pages: write
|
||||
id-token: write
|
||||
if: github.repository == 'php/php-src'
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
- name: Install dependencies
|
||||
run: pip install -r docs/requirements.txt
|
||||
- name: Check formatting
|
||||
run: make -C docs check-formatting
|
||||
- name: Publish
|
||||
if: github.event_name == 'push'
|
||||
uses: sphinx-notes/pages@v3
|
||||
with:
|
||||
checkout: false
|
||||
documentation_path: docs/source
|
2
.github/workflows/labeler.yml
vendored
2
.github/workflows/labeler.yml
vendored
|
@ -12,6 +12,6 @@ jobs:
|
|||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v5
|
||||
- uses: actions/labeler@v4
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
|
88
.github/workflows/nightly.yml
vendored
88
.github/workflows/nightly.yml
vendored
|
@ -54,7 +54,7 @@ jobs:
|
|||
runs-on: [self-hosted, gentoo, ppc64]
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.branch }}
|
||||
- name: System info
|
||||
|
@ -85,8 +85,6 @@ jobs:
|
|||
with:
|
||||
runTestsParameters: >-
|
||||
--asan -x
|
||||
- name: Extra tests
|
||||
uses: ./.github/actions/extra-tests
|
||||
ALPINE:
|
||||
if: inputs.run_alpine
|
||||
name: ALPINE_X64_ASAN_UBSAN_DEBUG_ZTS
|
||||
|
@ -95,7 +93,7 @@ jobs:
|
|||
image: 'alpine:3.20.1'
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.branch }}
|
||||
- name: apk
|
||||
|
@ -134,9 +132,8 @@ jobs:
|
|||
jitType: tracing
|
||||
runTestsParameters: >-
|
||||
--asan -x
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
- name: Extra tests
|
||||
uses: ./.github/actions/extra-tests
|
||||
- name: Notify Slack
|
||||
if: failure()
|
||||
uses: ./.github/actions/notify-slack
|
||||
|
@ -206,7 +203,7 @@ jobs:
|
|||
runs-on: ubuntu-${{ matrix.asan && inputs.asan_ubuntu_version || inputs.ubuntu_version }}
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.branch }}
|
||||
- name: Create MSSQL container
|
||||
|
@ -249,12 +246,14 @@ jobs:
|
|||
jitType: tracing
|
||||
runTestsParameters: >-
|
||||
${{ matrix.run_tests_parameters }}
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
- name: Test OpCache
|
||||
uses: ./.github/actions/test-linux
|
||||
with:
|
||||
runTestsParameters: >-
|
||||
${{ matrix.run_tests_parameters }}
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
- name: Test Function JIT
|
||||
# ASAN frequently timeouts. Each test run takes ~90 minutes, we can
|
||||
|
@ -265,9 +264,8 @@ jobs:
|
|||
jitType: function
|
||||
runTestsParameters: >-
|
||||
${{ matrix.run_tests_parameters }}
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
- name: Extra tests
|
||||
uses: ./.github/actions/extra-tests
|
||||
- name: Verify generated files are up to date
|
||||
uses: ./.github/actions/verify-generated-files
|
||||
- name: Notify Slack
|
||||
|
@ -306,7 +304,7 @@ jobs:
|
|||
FIREBIRD_PASSWORD: test
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.branch }}
|
||||
- name: apt
|
||||
|
@ -340,12 +338,14 @@ jobs:
|
|||
jitType: tracing
|
||||
runTestsParameters: >-
|
||||
${{ matrix.run_tests_parameters }}
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
- name: Test OpCache
|
||||
uses: ./.github/actions/test-linux
|
||||
with:
|
||||
runTestsParameters: >-
|
||||
${{ matrix.run_tests_parameters }}
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
- name: Test Function JIT
|
||||
uses: ./.github/actions/test-linux
|
||||
|
@ -353,9 +353,8 @@ jobs:
|
|||
jitType: function
|
||||
runTestsParameters: >-
|
||||
${{ matrix.run_tests_parameters }}
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
- name: Extra tests
|
||||
uses: ./.github/actions/extra-tests
|
||||
- name: Notify Slack
|
||||
if: failure()
|
||||
uses: ./.github/actions/notify-slack
|
||||
|
@ -374,7 +373,7 @@ jobs:
|
|||
runs-on: macos-${{ matrix.os }}
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.branch }}
|
||||
- name: brew
|
||||
|
@ -399,11 +398,13 @@ jobs:
|
|||
with:
|
||||
jitType: tracing
|
||||
runTestsParameters: >-
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
- name: Test OpCache
|
||||
uses: ./.github/actions/test-macos
|
||||
with:
|
||||
runTestsParameters: >-
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
- name: Test Function JIT
|
||||
if: matrix.os != '14' || !matrix.zts
|
||||
|
@ -411,9 +412,8 @@ jobs:
|
|||
with:
|
||||
jitType: function
|
||||
runTestsParameters: >-
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
- name: Extra tests
|
||||
uses: ./.github/actions/extra-tests
|
||||
- name: Verify generated files are up to date
|
||||
uses: ./.github/actions/verify-generated-files
|
||||
- name: Notify Slack
|
||||
|
@ -449,7 +449,7 @@ jobs:
|
|||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.branch }}
|
||||
- name: Create MSSQL container
|
||||
|
@ -474,6 +474,7 @@ jobs:
|
|||
with:
|
||||
jitType: tracing
|
||||
runTestsParameters: >-
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
- uses: codecov/codecov-action@v4
|
||||
if: ${{ !cancelled() }}
|
||||
|
@ -502,7 +503,7 @@ jobs:
|
|||
USE_TRACKED_ALLOC: 1
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.branch }}
|
||||
- name: apt
|
||||
|
@ -527,6 +528,7 @@ jobs:
|
|||
- name: Enable Opcache
|
||||
run: |
|
||||
echo memory_limit=-1 >> /etc/php.d/opcache.ini
|
||||
echo zend_extension=opcache.so > /etc/php.d/opcache.ini
|
||||
echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini
|
||||
echo opcache.enable=1 >> /etc/php.d/opcache.ini
|
||||
echo opcache.protect_memory=1 >> /etc/php.d/opcache.ini
|
||||
|
@ -553,17 +555,14 @@ jobs:
|
|||
repositories="amp cache dns file http parallel parser pipeline process serialization socket sync websocket-client websocket-server"
|
||||
X=0
|
||||
for repository in $repositories; do
|
||||
echo "::group::$repository"
|
||||
printf "Testing amp/%s\n" "$repository"
|
||||
git clone "https://github.com/amphp/$repository.git" "amphp-$repository" --depth 1
|
||||
cd "amphp-$repository"
|
||||
git rev-parse HEAD
|
||||
php /usr/bin/composer install --no-progress --ignore-platform-req=php+
|
||||
EXIT_CODE=0
|
||||
vendor/bin/phpunit || EXIT_CODE=$?
|
||||
echo -e "\n::endgroup::"
|
||||
if [ ${EXIT_CODE:-0} -gt 128 ]; then
|
||||
X=1;
|
||||
echo "Failed"
|
||||
fi
|
||||
cd ..
|
||||
done
|
||||
|
@ -587,17 +586,14 @@ jobs:
|
|||
repositories="async cache child-process datagram dns event-loop promise promise-stream promise-timer stream"
|
||||
X=0
|
||||
for repository in $repositories; do
|
||||
echo "::group::$repository"
|
||||
printf "Testing reactphp/%s\n" "$repository"
|
||||
git clone "https://github.com/reactphp/$repository.git" "reactphp-$repository" --depth 1
|
||||
cd "reactphp-$repository"
|
||||
git rev-parse HEAD
|
||||
php /usr/bin/composer install --no-progress --ignore-platform-req=php+
|
||||
EXIT_CODE=0
|
||||
vendor/bin/phpunit || EXIT_CODE=$?
|
||||
echo -e "\n::endgroup::"
|
||||
if [ $[EXIT_CODE:-0} -gt 128 ]; then
|
||||
X=1;
|
||||
echo "Failed"
|
||||
fi
|
||||
cd ..
|
||||
done
|
||||
|
@ -622,19 +618,15 @@ jobs:
|
|||
php /usr/bin/composer install --no-progress --ignore-platform-req=php+
|
||||
php ./phpunit install
|
||||
# Test causes a heap-buffer-overflow but I cannot reproduce it locally...
|
||||
php -r '$c = file_get_contents("src/Symfony/Component/HtmlSanitizer/Tests/HtmlSanitizerCustomTest.php"); $c = str_replace("public function testSanitizeDeepNestedString()", "#[\\PHPUnit\\Framework\\Attributes\\Group('"'"'skip'"'"')]\n public function testSanitizeDeepNestedString()", $c); file_put_contents("src/Symfony/Component/HtmlSanitizer/Tests/HtmlSanitizerCustomTest.php", $c);'
|
||||
php -r '$c = file_get_contents("src/Symfony/Component/HtmlSanitizer/Tests/HtmlSanitizerCustomTest.php"); $c = str_replace("public function testSanitizeDeepNestedString()", "/** @group skip */\n public function testSanitizeDeepNestedString()", $c); file_put_contents("src/Symfony/Component/HtmlSanitizer/Tests/HtmlSanitizerCustomTest.php", $c);'
|
||||
# Buggy FFI test in Symfony, see https://github.com/symfony/symfony/issues/47668
|
||||
php -r '$c = file_get_contents("src/Symfony/Component/VarDumper/Tests/Caster/FFICasterTest.php"); $c = str_replace("public function testCastNonTrailingCharPointer()", "#[\\PHPUnit\\Framework\\Attributes\\Group('"'"'skip'"'"')]\n public function testCastNonTrailingCharPointer()", $c); file_put_contents("src/Symfony/Component/VarDumper/Tests/Caster/FFICasterTest.php", $c);'
|
||||
php -r '$c = file_get_contents("src/Symfony/Component/VarDumper/Tests/Caster/FFICasterTest.php"); $c = str_replace("public function testCastNonTrailingCharPointer()", "/** @group skip */\n public function testCastNonTrailingCharPointer()", $c); file_put_contents("src/Symfony/Component/VarDumper/Tests/Caster/FFICasterTest.php", $c);'
|
||||
export SYMFONY_DEPRECATIONS_HELPER=max[total]=999
|
||||
X=0
|
||||
for component in $(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -printf '%h\n'); do
|
||||
echo "::group::$component"
|
||||
EXIT_CODE=0
|
||||
php ./phpunit $component --exclude-group tty --exclude-group benchmark --exclude-group intl-data --exclude-group transient --exclude-group skip || EXIT_CODE=$?
|
||||
echo -e "\n::endgroup::"
|
||||
php ./phpunit $component --exclude-group tty,benchmark,intl-data,transient --exclude-group skip || EXIT_CODE=$?
|
||||
if [ ${EXIT_CODE:-0} -gt 128 ]; then
|
||||
X=1;
|
||||
echo "Failed"
|
||||
fi
|
||||
done
|
||||
exit $X
|
||||
|
@ -705,7 +697,7 @@ jobs:
|
|||
runs-on: ubuntu-${{ inputs.ubuntu_version }}
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.branch }}
|
||||
- name: Create MSSQL container
|
||||
|
@ -727,18 +719,21 @@ jobs:
|
|||
uses: ./.github/actions/test-linux
|
||||
with:
|
||||
runTestsParameters: >-
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
--file-cache-prime
|
||||
- name: Test File Cache (prime shm, use shm)
|
||||
uses: ./.github/actions/test-linux
|
||||
with:
|
||||
runTestsParameters: >-
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
--file-cache-use
|
||||
- name: Test File Cache (prime shm, use file)
|
||||
uses: ./.github/actions/test-linux
|
||||
with:
|
||||
runTestsParameters: >-
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
--file-cache-use
|
||||
-d opcache.file_cache_only=1
|
||||
|
@ -746,6 +741,7 @@ jobs:
|
|||
uses: ./.github/actions/test-linux
|
||||
with:
|
||||
runTestsParameters: >-
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
--file-cache-prime
|
||||
-d opcache.file_cache_only=1
|
||||
|
@ -753,6 +749,7 @@ jobs:
|
|||
uses: ./.github/actions/test-linux
|
||||
with:
|
||||
runTestsParameters: >-
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
--file-cache-use
|
||||
-d opcache.file_cache_only=1
|
||||
|
@ -768,7 +765,7 @@ jobs:
|
|||
runs-on: ubuntu-${{ inputs.ubuntu_version }}
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.branch }}
|
||||
- name: apt
|
||||
|
@ -846,6 +843,7 @@ jobs:
|
|||
with:
|
||||
runTestsParameters: >-
|
||||
--msan
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
- name: Verify generated files are up to date
|
||||
uses: ./.github/actions/verify-generated-files
|
||||
|
@ -859,7 +857,7 @@ jobs:
|
|||
runs-on: ubuntu-${{ inputs.ubuntu_version }}
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.branch }}
|
||||
- name: apt
|
||||
|
@ -909,38 +907,38 @@ jobs:
|
|||
CXX: ccache g++
|
||||
steps:
|
||||
- name: git checkout PHP
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: php
|
||||
ref: ${{ inputs.branch }}
|
||||
- name: git checkout apcu
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: krakjoe/apcu
|
||||
path: apcu
|
||||
- name: git checkout imagick
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: Imagick/imagick
|
||||
path: imagick
|
||||
- name: git checkout memcached
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: php-memcached-dev/php-memcached
|
||||
path: memcached
|
||||
- name: git checkout redis
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: phpredis/phpredis
|
||||
path: redis
|
||||
- name: git checkout xdebug
|
||||
if: false
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: xdebug/xdebug
|
||||
path: xdebug
|
||||
- name: git checkout yaml
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: php/pecl-file_formats-yaml
|
||||
path: yaml
|
||||
|
@ -1050,7 +1048,7 @@ jobs:
|
|||
- name: git config
|
||||
run: git config --global core.autocrlf false && git config --global core.eol lf
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.branch }}
|
||||
- name: Setup
|
||||
|
@ -1068,10 +1066,9 @@ jobs:
|
|||
- zts: ${{ !inputs.run_freebsd_zts && true || '*never*' }}
|
||||
name: "FREEBSD_${{ matrix.zts && 'ZTS' || 'NTS' }}"
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 50
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ inputs.branch }}
|
||||
- name: FreeBSD
|
||||
|
@ -1079,4 +1076,3 @@ jobs:
|
|||
with:
|
||||
configurationParameters: >-
|
||||
--${{ matrix.zts && 'enable' || 'disable' }}-zts
|
||||
runExtraTests: true
|
||||
|
|
91
.github/workflows/push.yml
vendored
91
.github/workflows/push.yml
vendored
|
@ -10,12 +10,15 @@ on:
|
|||
- CONTRIBUTING.md
|
||||
- CODING_STANDARDS.md
|
||||
- .cirrus.yml
|
||||
- .travis.yml
|
||||
- travis/**
|
||||
- .circleci/**
|
||||
branches:
|
||||
- PHP-7.4
|
||||
- PHP-8.0
|
||||
- PHP-8.1
|
||||
- PHP-8.2
|
||||
- PHP-8.3
|
||||
- PHP-8.4
|
||||
- master
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
|
@ -27,6 +30,8 @@ on:
|
|||
- CONTRIBUTING.md
|
||||
- CODING_STANDARDS.md
|
||||
- .cirrus.yml
|
||||
- .travis.yml
|
||||
- travis/**
|
||||
- .circleci/**
|
||||
branches:
|
||||
- '**'
|
||||
|
@ -58,15 +63,6 @@ jobs:
|
|||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: test
|
||||
firebird:
|
||||
image: jacobalberty/firebird
|
||||
ports:
|
||||
- 3050:3050
|
||||
env:
|
||||
ISC_PASSWORD: test
|
||||
FIREBIRD_DATABASE: test.fdb
|
||||
FIREBIRD_USER: test
|
||||
FIREBIRD_PASSWORD: test
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
@ -78,11 +74,10 @@ jobs:
|
|||
zts: true
|
||||
asan: true
|
||||
name: "LINUX_X64_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}${{ matrix.asan && '_ASAN' || '' }}"
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 50
|
||||
runs-on: ubuntu-${{ !matrix.asan && '22' || '24' }}.04
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
- name: apt
|
||||
uses: ./.github/actions/apt-x64
|
||||
- name: System info
|
||||
|
@ -96,6 +91,9 @@ jobs:
|
|||
- name: Create MSSQL container
|
||||
if: ${{ !matrix.asan }}
|
||||
uses: ./.github/actions/setup-mssql
|
||||
- name: Create Oracle container
|
||||
if: ${{ !matrix.asan }}
|
||||
uses: ./.github/actions/setup-oracle
|
||||
- name: Setup Caddy server
|
||||
uses: ./.github/actions/setup-caddy
|
||||
- name: ccache
|
||||
|
@ -113,7 +111,7 @@ jobs:
|
|||
configurationParameters: >-
|
||||
--${{ matrix.debug && 'enable' || 'disable' }}-debug
|
||||
--${{ matrix.zts && 'enable' || 'disable' }}-zts
|
||||
${{ matrix.asan && 'CFLAGS="-fsanitize=undefined,address -fno-sanitize=function -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-fsanitize=undefined,address -fno-sanitize=function" CC=clang CXX=clang++' || '' }}
|
||||
${{ matrix.asan && 'CFLAGS="-fsanitize=undefined,address -fno-sanitize=function -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-fsanitize=undefined,address -fno-sanitize=function" CC=clang CXX=clang++ --disable-opcache-jit' || '' }}
|
||||
skipSlow: ${{ matrix.asan }}
|
||||
- name: make
|
||||
run: make -j$(/usr/bin/nproc) >/dev/null
|
||||
|
@ -125,11 +123,12 @@ jobs:
|
|||
- name: Test
|
||||
if: matrix.asan == false
|
||||
uses: ./.github/actions/test-linux
|
||||
- name: Test Tracing JIT
|
||||
- name: Test ${{ matrix.asan && 'OpCache' || 'Tracing JIT' }}
|
||||
uses: ./.github/actions/test-linux
|
||||
with:
|
||||
jitType: tracing
|
||||
jitType: ${{ matrix.asan && 'disable' || 'tracing' }}
|
||||
runTestsParameters: >-
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
${{ matrix.asan && '--asan -x' || '' }}
|
||||
- name: Verify generated files are up to date
|
||||
|
@ -139,14 +138,12 @@ jobs:
|
|||
if: github.repository == 'php/php-src' || github.event_name == 'pull_request'
|
||||
name: LINUX_X32_DEBUG_ZTS
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 50
|
||||
container:
|
||||
image: ubuntu:24.04
|
||||
image: ubuntu:22.04
|
||||
env:
|
||||
MYSQL_TEST_HOST: mysql
|
||||
PDO_MYSQL_TEST_DSN: mysql:host=mysql;dbname=test
|
||||
PDO_MYSQL_TEST_HOST: mysql
|
||||
PDO_FIREBIRD_TEST_DSN: firebird:dbname=firebird:test.fdb
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.3
|
||||
|
@ -155,18 +152,9 @@ jobs:
|
|||
env:
|
||||
MYSQL_DATABASE: test
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
firebird:
|
||||
image: jacobalberty/firebird
|
||||
ports:
|
||||
- 3050:3050
|
||||
env:
|
||||
ISC_PASSWORD: test
|
||||
FIREBIRD_DATABASE: test.fdb
|
||||
FIREBIRD_USER: test
|
||||
FIREBIRD_PASSWORD: test
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
- name: apt
|
||||
uses: ./.github/actions/apt-x32
|
||||
- name: ccache
|
||||
|
@ -189,27 +177,20 @@ jobs:
|
|||
with:
|
||||
jitType: tracing
|
||||
runTestsParameters: >-
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
MACOS_DEBUG_NTS:
|
||||
if: github.repository == 'php/php-src' || github.event_name == 'pull_request'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: 15
|
||||
arch: ARM64
|
||||
name: MACOS_${{ matrix.arch }}_DEBUG_NTS
|
||||
runs-on: macos-${{ matrix.os }}
|
||||
timeout-minutes: 50
|
||||
runs-on: macos-13
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
- name: brew
|
||||
uses: ./.github/actions/brew
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: "${{github.job}}-${{matrix.os}}-${{hashFiles('main/php_version.h')}}"
|
||||
key: "${{github.job}}-${{hashFiles('main/php_version.h')}}"
|
||||
append-timestamp: false
|
||||
save: ${{ github.event_name != 'pull_request' }}
|
||||
- name: ./configure
|
||||
|
@ -218,7 +199,7 @@ jobs:
|
|||
configurationParameters: --enable-debug --disable-zts
|
||||
- name: make
|
||||
run: |-
|
||||
export PATH="$(brew --prefix)/opt/bison/bin:$PATH"
|
||||
export PATH="/usr/local/opt/bison/bin:$PATH"
|
||||
make -j$(sysctl -n hw.logicalcpu) >/dev/null
|
||||
- name: make install
|
||||
run: sudo make install
|
||||
|
@ -227,20 +208,21 @@ jobs:
|
|||
with:
|
||||
jitType: tracing
|
||||
runTestsParameters: >-
|
||||
-d zend_extension=opcache.so
|
||||
-d opcache.enable_cli=1
|
||||
-d opcache.protect_memory=1
|
||||
- name: Verify generated files are up to date
|
||||
uses: ./.github/actions/verify-generated-files
|
||||
WINDOWS:
|
||||
if: github.repository == 'php/php-src' || github.event_name == 'pull_request'
|
||||
name: WINDOWS_X64_ZTS
|
||||
runs-on: windows-2022
|
||||
timeout-minutes: 50
|
||||
env:
|
||||
PHP_BUILD_CACHE_BASE_DIR: C:\build-cache
|
||||
PHP_BUILD_OBJ_DIR: C:\obj
|
||||
PHP_BUILD_CACHE_SDK_DIR: C:\build-cache\sdk
|
||||
PHP_BUILD_SDK_BRANCH: php-sdk-2.3.0
|
||||
PHP_BUILD_CRT: vs17
|
||||
PHP_BUILD_CRT: vs16
|
||||
PLATFORM: x64
|
||||
THREAD_SAFE: "1"
|
||||
INTRINSICS: AVX2
|
||||
|
@ -250,7 +232,7 @@ jobs:
|
|||
- name: git config
|
||||
run: git config --global core.autocrlf false && git config --global core.eol lf
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup
|
||||
uses: ./.github/actions/setup-windows
|
||||
- name: Build
|
||||
|
@ -260,17 +242,12 @@ jobs:
|
|||
BENCHMARKING:
|
||||
name: BENCHMARKING
|
||||
if: github.repository == 'php/php-src' || github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 50
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
# ASLR can cause a lot of noise due to missed sse opportunities for memcpy
|
||||
# and other operations, so we disable it during benchmarking.
|
||||
- name: Disable ASLR
|
||||
run: echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
|
||||
- name: apt
|
||||
run: |
|
||||
set -x
|
||||
|
@ -296,6 +273,7 @@ jobs:
|
|||
./configure \
|
||||
--disable-debug \
|
||||
--enable-mbstring \
|
||||
--enable-opcache \
|
||||
--enable-option-checking=fatal \
|
||||
--enable-sockets \
|
||||
--enable-werror \
|
||||
|
@ -315,6 +293,7 @@ jobs:
|
|||
sudo mkdir -p /etc/php.d
|
||||
sudo chmod 777 /etc/php.d
|
||||
echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini
|
||||
echo zend_extension=opcache.so >> /etc/php.d/opcache.ini
|
||||
echo opcache.enable=1 >> /etc/php.d/opcache.ini
|
||||
echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini
|
||||
- name: Setup
|
||||
|
@ -326,7 +305,7 @@ jobs:
|
|||
mysql -uroot -proot -e "CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'wordpress'; FLUSH PRIVILEGES;"
|
||||
mysql -uroot -proot -e "GRANT ALL PRIVILEGES ON *.* TO 'wordpress'@'localhost' WITH GRANT OPTION;"
|
||||
- name: git checkout benchmarking-data
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: php/benchmarking-data
|
||||
ssh-key: ${{ secrets.BENCHMARKING_DATA_DEPLOY_KEY }}
|
||||
|
@ -357,18 +336,12 @@ jobs:
|
|||
${{ github.sha }} \
|
||||
$(git merge-base ${{ github.event.pull_request.base.sha }} ${{ github.sha }}) \
|
||||
> $GITHUB_STEP_SUMMARY
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: profiles
|
||||
path: ${{ github.workspace }}/benchmark/profiles
|
||||
retention-days: 30
|
||||
FREEBSD:
|
||||
if: github.repository == 'php/php-src' || github.event_name == 'pull_request'
|
||||
name: FREEBSD
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 50
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v5
|
||||
uses: actions/checkout@v4
|
||||
- name: FreeBSD
|
||||
uses: ./.github/actions/freebsd
|
||||
|
|
300
.github/workflows/real-time-benchmark.yml
vendored
300
.github/workflows/real-time-benchmark.yml
vendored
|
@ -1,300 +0,0 @@
|
|||
name: Real-time Benchmark
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 0 * * *"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
pull_request:
|
||||
description: 'PR number that is going to be benchmarked (e.g. "1234")'
|
||||
required: true
|
||||
type: number
|
||||
jit:
|
||||
description: 'Whether JIT is benchmarked'
|
||||
required: false
|
||||
default: "0"
|
||||
type: choice
|
||||
options:
|
||||
- "0"
|
||||
- "1"
|
||||
instruction_count:
|
||||
description: 'Whether Valgrind instruction count should be measured'
|
||||
required: true
|
||||
default: "0"
|
||||
type: choice
|
||||
options:
|
||||
- "0"
|
||||
- "1"
|
||||
opcache:
|
||||
description: 'Whether opcache is enabled for the benchmarked commit'
|
||||
required: true
|
||||
default: "1"
|
||||
type: choice
|
||||
options:
|
||||
- "0"
|
||||
- "1"
|
||||
- "2"
|
||||
baseline_opcache:
|
||||
description: 'Whether opcache is enabled for the baseline commit'
|
||||
required: true
|
||||
default: "1"
|
||||
type: choice
|
||||
options:
|
||||
- "0"
|
||||
- "1"
|
||||
- "2"
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
cancel-in-progress: false
|
||||
jobs:
|
||||
REAL_TIME_BENCHMARK:
|
||||
name: REAL_TIME_BENCHMARK
|
||||
if: github.repository == 'php/php-src' || github.event_name == 'workflow_dispatch'
|
||||
runs-on: ubuntu-22.04
|
||||
env:
|
||||
REPOSITORY: ${{ github.repository }}
|
||||
BRANCH: "master"
|
||||
COMMIT: ${{ github.sha }}
|
||||
BASELINE_COMMIT: "d5f6e56610c729710073350af318c4ea1b292cfe"
|
||||
ID: "master"
|
||||
OPCACHE: ${{ inputs.opcache || '1' }}
|
||||
BASELINE_OPCACHE: ${{ inputs.baseline_opcache || '2' }}
|
||||
JIT: ${{ inputs.jit || '1' }}
|
||||
INSTRUCTION_COUNT: ${{ inputs.instruction_count || '0' }}
|
||||
YEAR: ""
|
||||
steps:
|
||||
- name: Setup benchmark environment
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
YEAR="$(date '+%Y')"
|
||||
echo "YEAR=$YEAR" >> $GITHUB_ENV
|
||||
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||
PR_INFO=$(gh pr view ${{ inputs.pull_request }} --json headRepositoryOwner,headRepository,headRefName,headRefOid,baseRefOid --repo ${{ github.repository }} | jq -r '.headRepositoryOwner.login, .headRepository.name, .headRefName, .headRefOid, .baseRefOid')
|
||||
|
||||
REPOSITORY="$(echo "$PR_INFO" | sed -n '1p')/$(echo "$PR_INFO" | sed -n '2p')"
|
||||
echo "REPOSITORY=$REPOSITORY" >> $GITHUB_ENV
|
||||
|
||||
BRANCH=$(echo "$PR_INFO" | sed -n '3p')
|
||||
echo "BRANCH=$BRANCH" >> $GITHUB_ENV
|
||||
|
||||
COMMIT=$(echo "$PR_INFO" | sed -n '4p')
|
||||
echo "COMMIT=$COMMIT" >> $GITHUB_ENV
|
||||
|
||||
BASELINE_COMMIT=$(echo "$PR_INFO" | sed -n '5p')
|
||||
echo "BASELINE_COMMIT=$BASELINE_COMMIT" >> $GITHUB_ENV
|
||||
|
||||
echo "ID=benchmarked" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
set -ex
|
||||
sudo apt-get update
|
||||
sudo apt-get install gpg
|
||||
|
||||
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
|
||||
gpg --no-default-keyring --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg --fingerprint
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y terraform=1.5.7-*
|
||||
- name: Checkout benchmark suite
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
repository: 'kocsismate/php-version-benchmarks'
|
||||
ref: 'main'
|
||||
fetch-depth: 1
|
||||
path: 'php-version-benchmarks'
|
||||
- name: Checkout php-src (benchmarked version)
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
repository: '${{ env.REPOSITORY }}'
|
||||
ref: '${{ env.COMMIT }}'
|
||||
fetch-depth: 100
|
||||
path: 'php-version-benchmarks/tmp/php_${{ env.ID }}'
|
||||
- name: Checkout php-src (baseline version)
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
repository: '${{ env.REPOSITORY }}'
|
||||
ref: '${{ env.BASELINE_COMMIT }}'
|
||||
fetch-depth: 100
|
||||
path: 'php-version-benchmarks/tmp/php_baseline'
|
||||
- name: Setup benchmark results
|
||||
run: |
|
||||
git config --global user.name "Benchmark"
|
||||
git config --global user.email "benchmark@php.net"
|
||||
|
||||
rm -rf ./php-version-benchmarks/docs/results
|
||||
- name: Checkout benchmark data
|
||||
if: github.event_name != 'workflow_dispatch'
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
repository: php/real-time-benchmark-data
|
||||
ssh-key: ${{ secrets.PHP_VERSION_BENCHMARK_RESULTS_DEPLOY_KEY }}
|
||||
path: 'php-version-benchmarks/docs/results'
|
||||
- name: Setup infra config
|
||||
run: |
|
||||
set -e
|
||||
|
||||
cp ./php-version-benchmarks/config/infra/aws/x86_64-metal.ini.dist ./php-version-benchmarks/config/infra/aws/x86_64-metal.ini
|
||||
ESCAPED_DOCKER_REGISTRY=$(printf '%s\n' "${{ secrets.PHP_VERSION_BENCHMARK_DOCKER_REGISTRY }}" | sed -e 's/[\/&]/\\&/g')
|
||||
sed -i "s/INFRA_DOCKER_REGISTRY=public.ecr.aws\/abcdefgh/INFRA_DOCKER_REGISTRY=$ESCAPED_DOCKER_REGISTRY/g" ./php-version-benchmarks/config/infra/aws/x86_64-metal.ini
|
||||
sed -i "s/INFRA_MEASURE_INSTRUCTION_COUNT=0/INFRA_MEASURE_INSTRUCTION_COUNT=${{ env.INSTRUCTION_COUNT }}/g" ./php-version-benchmarks/config/infra/aws/x86_64-metal.ini
|
||||
cp ./php-version-benchmarks/build/infrastructure/config/aws.tfvars.dist ./php-version-benchmarks/build/infrastructure/config/aws.tfvars
|
||||
sed -i 's/access_key = ""/access_key = "${{ secrets.PHP_VERSION_BENCHMARK_AWS_ACCESS_KEY }}"/g' ./php-version-benchmarks/build/infrastructure/config/aws.tfvars
|
||||
sed -i 's/secret_key = ""/secret_key = "${{ secrets.PHP_VERSION_BENCHMARK_AWS_SECRET_KEY }}"/g' ./php-version-benchmarks/build/infrastructure/config/aws.tfvars
|
||||
sed -i 's/github_token = ""/github_token = "${{ secrets.GITHUB_TOKEN }}"/g' ./php-version-benchmarks/build/infrastructure/config/aws.tfvars
|
||||
- name: Setup PHP config - baseline PHP version
|
||||
run: |
|
||||
set -e
|
||||
|
||||
BASELINE_SHORT_SHA="$(echo "${{ env.BASELINE_COMMIT }}" | cut -c1-4)"
|
||||
|
||||
cat << EOF > ./php-version-benchmarks/config/php/baseline.ini
|
||||
PHP_NAME="PHP - baseline@$BASELINE_SHORT_SHA"
|
||||
PHP_ID=php_baseline
|
||||
|
||||
PHP_REPO=https://github.com/${{ env.REPOSITORY }}.git
|
||||
PHP_BRANCH=${{ env.BRANCH }}
|
||||
PHP_COMMIT=${{ env.BASELINE_COMMIT }}
|
||||
|
||||
PHP_OPCACHE=${{ env.BASELINE_OPCACHE }}
|
||||
PHP_JIT=0
|
||||
EOF
|
||||
- name: Setup PHP config - baseline PHP version with JIT
|
||||
if: github.event_name == 'workflow_dispatch' && inputs.jit == '1'
|
||||
run: |
|
||||
set -e
|
||||
|
||||
BASELINE_SHORT_SHA="$(echo "${{ env.BASELINE_COMMIT }}" | cut -c1-4)"
|
||||
|
||||
cat << EOF > ./php-version-benchmarks/config/php/baseline_jit.ini
|
||||
PHP_NAME="PHP - baseline@$BASELINE_SHORT_SHA (JIT)"
|
||||
PHP_ID=php_baseline_jit
|
||||
|
||||
PHP_REPO=https://github.com/${{ env.REPOSITORY }}.git
|
||||
PHP_BRANCH=${{ env.BRANCH }}
|
||||
PHP_COMMIT=${{ env.BASELINE_COMMIT }}
|
||||
|
||||
PHP_OPCACHE=${{ env.BASELINE_OPCACHE }}
|
||||
PHP_JIT=${{ env.JIT }}
|
||||
EOF
|
||||
|
||||
git clone ./php-version-benchmarks/tmp/php_baseline/ ./php-version-benchmarks/tmp/php_baseline_jit
|
||||
- name: Setup PHP config - previous PHP version
|
||||
if: github.event_name != 'workflow_dispatch'
|
||||
run: |
|
||||
set -e
|
||||
|
||||
DATABASE="./php-version-benchmarks/docs/results/${{ env.YEAR }}/database.tsv"
|
||||
if [ -f "$DATABASE" ]; then
|
||||
LAST_RESULT_SHA="$(tail -n 2 "$DATABASE" | head -n 1 | cut -f 6)"
|
||||
else
|
||||
YESTERDAY="$(date -d "-2 day 23:59:59" '+%Y-%m-%d %H:%M:%S')"
|
||||
LAST_RESULT_SHA="$(cd ./php-version-benchmarks/tmp/php_${{ env.ID }}/ && git --no-pager log --until="$YESTERDAY" -n 1 --pretty='%H')"
|
||||
fi
|
||||
|
||||
cat << EOF > ./php-version-benchmarks/config/php/previous.ini
|
||||
PHP_NAME="PHP - previous ${{ env.BRANCH }}"
|
||||
PHP_ID=php_previous
|
||||
|
||||
PHP_REPO=https://github.com/${{ env.REPOSITORY }}.git
|
||||
PHP_BRANCH=${{ env.BRANCH }}
|
||||
PHP_COMMIT=$LAST_RESULT_SHA
|
||||
|
||||
PHP_OPCACHE=1
|
||||
PHP_JIT=0
|
||||
EOF
|
||||
- name: Setup PHP config - benchmarked PHP version
|
||||
run: |
|
||||
set -e
|
||||
|
||||
cat << EOF > ./php-version-benchmarks/config/php/this.ini
|
||||
PHP_NAME="PHP - ${{ env.BRANCH }}"
|
||||
PHP_ID=php_${{ env.ID }}
|
||||
|
||||
PHP_REPO=https://github.com/${{ env.REPOSITORY }}.git
|
||||
PHP_BRANCH=${{ env.BRANCH }}
|
||||
PHP_COMMIT=${{ env.COMMIT }}
|
||||
|
||||
PHP_OPCACHE=${{ env.OPCACHE }}
|
||||
PHP_JIT=0
|
||||
EOF
|
||||
- name: Setup PHP config - benchmarked PHP version with JIT
|
||||
if: env.JIT == '1'
|
||||
run: |
|
||||
set -e
|
||||
|
||||
cat << EOF > ./php-version-benchmarks/config/php/this_jit.ini
|
||||
PHP_NAME="PHP - ${{ env.BRANCH }} (JIT)"
|
||||
PHP_ID=php_${{ env.ID }}_jit
|
||||
|
||||
PHP_REPO=https://github.com/${{ env.REPOSITORY }}.git
|
||||
PHP_BRANCH=${{ env.BRANCH }}
|
||||
PHP_COMMIT=${{ env.COMMIT }}
|
||||
|
||||
PHP_OPCACHE=${{ env.OPCACHE }}
|
||||
PHP_JIT=${{ env.JIT }}
|
||||
EOF
|
||||
|
||||
git clone ./php-version-benchmarks/tmp/php_${{ env.ID }}/ ./php-version-benchmarks/tmp/php_${{ env.ID }}_jit
|
||||
- name: Setup test config
|
||||
run: |
|
||||
set -e
|
||||
|
||||
cp ./php-version-benchmarks/config/test/1_laravel.ini.dist ./php-version-benchmarks/config/test/1_laravel.ini
|
||||
cp ./php-version-benchmarks/config/test/2_symfony_main.ini.dist ./php-version-benchmarks/config/test/2_symfony_main.ini
|
||||
cp ./php-version-benchmarks/config/test/4_wordpress.ini.dist ./php-version-benchmarks/config/test/4_wordpress.ini
|
||||
cp ./php-version-benchmarks/config/test/5_bench.php.ini.dist ./php-version-benchmarks/config/test/5_bench.php.ini
|
||||
cp ./php-version-benchmarks/config/test/6_micro_bench.php.ini.dist ./php-version-benchmarks/config/test/6_micro_bench.php.ini
|
||||
- name: Run benchmark
|
||||
run: ./php-version-benchmarks/benchmark.sh run aws
|
||||
- name: Store results
|
||||
if: github.repository == 'php/php-src' && github.event_name != 'workflow_dispatch'
|
||||
run: |
|
||||
set -ex
|
||||
|
||||
cd ./php-version-benchmarks/docs/results
|
||||
git pull --autostash
|
||||
if [ -e ".git/MERGE_HEAD" ]; then
|
||||
echo "Merging, can't proceed"
|
||||
exit 1
|
||||
fi
|
||||
git add .
|
||||
if git diff --cached --quiet; then
|
||||
exit 1
|
||||
fi
|
||||
git commit -m "Add result for ${{ github.repository }}@${{ github.sha }}"
|
||||
git push
|
||||
- name: Upload artifact
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: results
|
||||
path: ./php-version-benchmarks/docs/results/${{ env.YEAR }}
|
||||
retention-days: 30
|
||||
- name: Comment results
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
cd ./php-version-benchmarks/tmp/php_${{ env.ID }}
|
||||
NEWEST_RESULT_DIRECTORY=$(ls -td ${{ github.workspace }}/php-version-benchmarks/docs/results/${{ env.YEAR }}/*/ | head -1)
|
||||
gh pr comment ${{ inputs.pull_request }} --body-file "${NEWEST_RESULT_DIRECTORY}result.md" --repo ${{ github.repository }}
|
||||
- name: Cleanup
|
||||
if: always()
|
||||
run: |
|
||||
set -ex
|
||||
|
||||
rm -rf ./php-version-benchmarks/tmp/
|
||||
rm -f ./php-version-benchmarks/build/infrastructure/config/*.tfvars
|
||||
rm -rf ./php-version-benchmarks/build/infrastructure/aws/.terraform/
|
||||
rm -f ./php-version-benchmarks/build/infrastructure/aws/.terraform.lock.hcl
|
||||
rm -f ./php-version-benchmarks/build/infrastructure/aws/aws.tfplan
|
||||
rm -f ./php-version-benchmarks/build/infrastructure/aws/terraform.tfstate
|
||||
rm -f ./php-version-benchmarks/build/infrastructure/aws/terraform.tfstate.backup
|
||||
rm -f ./php-version-benchmarks/config/infra/aws/*.ini
|
2
.github/workflows/remove-needs-feedback.yml
vendored
2
.github/workflows/remove-needs-feedback.yml
vendored
|
@ -10,7 +10,7 @@ permissions:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
if: "github.repository == 'php/php-src' && contains(github.event.issue.labels.*.name, 'Status: Needs Feedback') && github.event.issue.user.login == github.event.sender.login"
|
||||
if: "github.repository_owner == 'php' && contains(github.event.issue.labels.*.name, 'Status: Needs Feedback') && github.event.issue.user.login == github.event.sender.login"
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
|
|
2
.github/workflows/root.yml
vendored
2
.github/workflows/root.yml
vendored
|
@ -13,7 +13,7 @@ jobs:
|
|||
outputs:
|
||||
branches: ${{ steps.set-matrix.outputs.branches }}
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
# Set fetch-depth to 0 to clone the full repository
|
||||
# including all branches. This is required to find
|
||||
|
|
21
.gitignore
vendored
21
.gitignore
vendored
|
@ -81,7 +81,8 @@ Makefile
|
|||
Makefile.fragments
|
||||
Makefile.objects
|
||||
|
||||
# Directories for shared object files generated by `./configure`
|
||||
# Directories for shared object files and headers generated by `./configure`
|
||||
include/
|
||||
libs/
|
||||
modules/
|
||||
|
||||
|
@ -131,7 +132,6 @@ config.h.in
|
|||
/sapi/cgi/php-cgi
|
||||
/sapi/fpm/php-fpm
|
||||
/sapi/phpdbg/phpdbg
|
||||
/sapi/fuzzer/php-fuzz-*
|
||||
/scripts/php-config
|
||||
/scripts/phpize
|
||||
php
|
||||
|
@ -141,7 +141,7 @@ php
|
|||
# ------------------------------------------------------------------------------
|
||||
/ext/json/json_scanner.c
|
||||
/ext/json/php_json_scanner_defs.h
|
||||
/ext/pdo*/*_sql_parser.c
|
||||
/ext/pdo/pdo_sql_parser.c
|
||||
/ext/phar/phar_path_check.c
|
||||
/ext/standard/url_scanner_ex.c
|
||||
/ext/standard/var_unserializer.c
|
||||
|
@ -171,7 +171,6 @@ php
|
|||
# ------------------------------------------------------------------------------
|
||||
|
||||
# Miscellaneous extensions files
|
||||
/ext/fileinfo/libmagic.orig/
|
||||
/ext/opcache/jit/zend_jit_x86.c
|
||||
/ext/opcache/jit/zend_jit_arm64.c
|
||||
/ext/opcache/minilua
|
||||
|
@ -238,7 +237,6 @@ php
|
|||
**/tests/**/*.exp
|
||||
**/tests/**/*.log
|
||||
**/tests/**/*.sh
|
||||
**/tests/**/*.stdin
|
||||
|
||||
# Generated by some test cases
|
||||
**/tests/**/*.db
|
||||
|
@ -262,7 +260,7 @@ phpt.*
|
|||
tmp-php.ini
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Generated by GCC's gcov and LCOV via build/Makefile.gcov
|
||||
# Generated by GCC's gcov and LCOV via build/Makefile.gcov and gcov.php.net
|
||||
# ------------------------------------------------------------------------------
|
||||
*.gcda
|
||||
*.gcno
|
||||
|
@ -274,7 +272,6 @@ tmp-php.ini
|
|||
# ------------------------------------------------------------------------------
|
||||
# Archives generated during the PHP release process
|
||||
# ------------------------------------------------------------------------------
|
||||
/*.manifest
|
||||
/*.tar.gz
|
||||
/*.tar.bz2
|
||||
/*.tar.xz
|
||||
|
@ -285,6 +282,8 @@ tmp-php.ini
|
|||
# ------------------------------------------------------------------------------
|
||||
# Generated by `./configure --enable-dtrace` for using DTrace framework
|
||||
# ------------------------------------------------------------------------------
|
||||
/ext/oci8/oci8_dtrace_gen.h
|
||||
/ext/oci8/oci8_dtrace_gen.h.bak
|
||||
/Zend/zend_dtrace_gen.h
|
||||
/Zend/zend_dtrace_gen.h.bak
|
||||
|
||||
|
@ -295,13 +294,6 @@ tmp-php.ini
|
|||
/junit.out.xml
|
||||
/.ccache/
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Editor configuration directories
|
||||
# ------------------------------------------------------------------------------
|
||||
/.idea/
|
||||
/.vscode/
|
||||
/.zed/
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Additional test build files
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -314,6 +306,5 @@ tmp-php.ini
|
|||
!/ext/fileinfo/libmagic/config.h
|
||||
!/ext/fileinfo/libmagic.patch
|
||||
!/ext/fileinfo/magicdata.patch
|
||||
!/ext/lexbor/patches/*.patch
|
||||
!/ext/pcre/pcre2lib/config.h
|
||||
!/win32/build/Makefile
|
||||
|
|
92
.travis.yml
Normal file
92
.travis.yml
Normal file
|
@ -0,0 +1,92 @@
|
|||
git:
|
||||
quiet: true
|
||||
|
||||
dist: focal
|
||||
language: c
|
||||
os: linux
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- locales
|
||||
- language-pack-de
|
||||
- re2c
|
||||
- ccache
|
||||
- mysql-server
|
||||
- libaspell-dev
|
||||
- libbz2-dev
|
||||
- libcurl4-gnutls-dev
|
||||
- libenchant-dev
|
||||
- libfreetype6-dev
|
||||
- libgmp-dev
|
||||
- libicu-dev
|
||||
- libjpeg-dev
|
||||
- libkrb5-dev
|
||||
- libonig-dev
|
||||
- libpng-dev
|
||||
- libpq-dev
|
||||
- libpspell-dev
|
||||
- libsasl2-dev
|
||||
- libsqlite3-dev
|
||||
- libsodium-dev
|
||||
- libtidy-dev
|
||||
- libwebp-dev
|
||||
- libxml2-dev
|
||||
- libxpm-dev
|
||||
- libxslt1-dev
|
||||
- libzip-dev
|
||||
|
||||
|
||||
services:
|
||||
- mysql
|
||||
- postgresql
|
||||
|
||||
notifications:
|
||||
email:
|
||||
on_failure: change
|
||||
irc:
|
||||
template:
|
||||
- "%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message} - Change view : %{compare_url} - Build details : %{build_url}"
|
||||
channels:
|
||||
- "irc.efnet.org#php.pecl"
|
||||
on_success: change
|
||||
on_failure: always
|
||||
|
||||
cache:
|
||||
apt: true
|
||||
ccache: true
|
||||
|
||||
env:
|
||||
global:
|
||||
- MYSQL_TEST_HOST=127.0.0.1
|
||||
- MYSQL_TEST_USER=travis
|
||||
- PDO_MYSQL_TEST_DSN="mysql:host=127.0.0.1;dbname=test"
|
||||
- PDO_MYSQL_TEST_USER=travis
|
||||
- PDO_MYSQL_TEST_PASS=
|
||||
- PDO_MYSQL_TEST_HOST=127.0.0.1
|
||||
- PDO_PGSQL_TEST_DSN="pgsql:host=localhost port=5432 dbname=test user=postgres password="
|
||||
- REPORT_EXIT_STATUS=1
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- env: ENABLE_ZTS=1 ENABLE_DEBUG=1 S390X=1
|
||||
arch: s390x
|
||||
|
||||
before_script:
|
||||
- ccache --version
|
||||
- ccache --zero-stats
|
||||
- export USE_CCACHE=1
|
||||
# Enable IPv6
|
||||
- sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6'
|
||||
# Compile PHP
|
||||
- travis_wait ./travis/compile.sh
|
||||
# Setup Extensions
|
||||
- ./travis/setup-mysql.sh
|
||||
- ./travis/setup-pgsql.sh
|
||||
|
||||
# Run PHPs run-tests.php
|
||||
script:
|
||||
- ./travis/test.sh -d opcache.jit_buffer_size=16M -d opcache.jit=tracing
|
||||
- sapi/cli/php -d extension_dir=`pwd`/modules -r 'dl("zend_test");'
|
||||
|
||||
after_success:
|
||||
- ccache --show-stats
|
|
@ -9,10 +9,9 @@ rewritten to comply with these rules.
|
|||
|
||||
1. Document your code in source files and the manual. (tm)
|
||||
|
||||
1. PHP is implemented in C11.
|
||||
For instance, the optional fixed-width integers from
|
||||
1. PHP is implemented in C99. The optional fixed-width integers from
|
||||
stdint.h (int8_t, int16_t, int32_t, int64_t and their unsigned
|
||||
counterparts) are supposed to be available.
|
||||
counterparts) must be available.
|
||||
|
||||
1. Functions that are given pointers to resources should not free them.
|
||||
|
||||
|
@ -56,6 +55,11 @@ rewritten to comply with these rules.
|
|||
the source. Although the `PHP_*` macros are mostly aliased to the `ZEND_*`
|
||||
macros it gives a better understanding on what kind of macro you're calling.
|
||||
|
||||
1. When commenting out code using a `#if` statement, do NOT use `0` only.
|
||||
Instead, use `"<git username here>_0"`. For example, `#if FOO_0`,
|
||||
where `FOO` is your git user `foo`. This allows easier tracking of why
|
||||
code was commented out, especially in bundled libraries.
|
||||
|
||||
1. Do not define functions that are not available. For instance, if a library is
|
||||
missing a function, do not define the PHP version of the function, and do
|
||||
not raise a run-time error about the function not existing. End users should
|
||||
|
@ -148,74 +152,62 @@ rewritten to comply with these rules.
|
|||
1. Method names follow the *studlyCaps* (also referred to as *bumpy case* or
|
||||
*camel caps*) naming convention, with care taken to minimize the letter
|
||||
count. The initial letter of the name is lowercase, and each letter that
|
||||
starts a new "word" is capitalized.
|
||||
starts a new `word` is capitalized:
|
||||
|
||||
1. Class names should be descriptive nouns in *PascalCase* and as short as
|
||||
possible. Each word in the class name should start with a capital letter,
|
||||
without underscore delimiters. The class name should be prefixed with the
|
||||
name of the "parent set" (e.g. the name of the extension) if no namespaces
|
||||
are used.
|
||||
|
||||
1. Abbreviations and acronyms as well as initialisms should be avoided wherever
|
||||
possible, unless they are much more widely used than the long form (e.g. HTTP
|
||||
or URL). Abbreviations, acronyms, and initialisms should be treated like
|
||||
regular words, thus they should be written with an uppercase first character,
|
||||
followed by lowercase characters.
|
||||
|
||||
1. Diverging from this policy is allowed to keep internal consistency within a
|
||||
single extension, if the name follows an established, language-agnostic
|
||||
standard, or for other reasons, if those reasons are properly justified
|
||||
and voted on as part of the RFC process.
|
||||
|
||||
|
||||
Good method names:
|
||||
Good:
|
||||
|
||||
```php
|
||||
connect()
|
||||
getData()
|
||||
buildSomeWidget()
|
||||
performHttpRequest()
|
||||
```
|
||||
|
||||
Bad method names:
|
||||
Bad:
|
||||
|
||||
```php
|
||||
get_Data()
|
||||
buildsomewidget()
|
||||
getI()
|
||||
performHTTPRequest()
|
||||
```
|
||||
|
||||
Good class names:
|
||||
1. Class names should be descriptive nouns in *PascalCase* and as short as
|
||||
possible. Each word in the class name should start with a capital letter,
|
||||
without underscore delimiters. The class name should be prefixed with the
|
||||
name of the "parent set" (e.g. the name of the extension) if no namespaces
|
||||
are used. Abbreviations and acronyms as well as initialisms should be
|
||||
avoided wherever possible, unless they are much more widely used than the
|
||||
long form (e.g. HTTP or URL). Abbreviations start with a capital letter
|
||||
followed by lowercase letters, whereas acronyms and initialisms are written
|
||||
according to their standard notation. Usage of acronyms and initialisms is
|
||||
not allowed if they are not widely adopted and recognized as such.
|
||||
|
||||
Good:
|
||||
|
||||
```php
|
||||
Curl
|
||||
CurlResponse
|
||||
HttpStatusCode
|
||||
Url
|
||||
BtreeMap // B-tree Map
|
||||
UserId // User Identifier
|
||||
HTTPStatusCode
|
||||
URL
|
||||
BTreeMap // B-tree Map
|
||||
Id // Identifier
|
||||
ID // Identity Document
|
||||
Char // Character
|
||||
Intl // Internationalization
|
||||
Ssl\Certificate
|
||||
Ssl\Crl // Certificate Revocation List
|
||||
Ssl\CrlUrl
|
||||
Radar // Radio Detecting and Ranging
|
||||
```
|
||||
|
||||
Bad class names:
|
||||
Bad:
|
||||
|
||||
```php
|
||||
curl
|
||||
curl_response
|
||||
HTTPStatusCode
|
||||
URL
|
||||
BTreeMap
|
||||
UserID // User Identifier
|
||||
HttpStatusCode
|
||||
Url
|
||||
BtreeMap
|
||||
ID // Identifier
|
||||
CHAR
|
||||
INTL
|
||||
SSL\Certificate
|
||||
SSL\CRL
|
||||
SSL\CRLURL
|
||||
RADAR // Radio Detecting and Ranging
|
||||
```
|
||||
|
||||
## Internal function naming conventions
|
||||
|
|
|
@ -32,12 +32,6 @@ had several contributions accepted, commit privileges are often quickly granted.
|
|||
PHP welcomes pull requests to [add tests](#writing-tests), fix bugs and to
|
||||
implement RFCs. Please be sure to include tests as appropriate!
|
||||
|
||||
By submitting a pull request, you certify that you have the necessary rights
|
||||
to submit the work, that the work does not violate any third-party rights
|
||||
(including those of your employer, if applicable), and that you license your
|
||||
contribution under the PHP License or under another license if explicitly
|
||||
accepted by the PHP project maintainers.
|
||||
|
||||
If you are fixing a bug, then please submit your PR against the lowest actively
|
||||
supported branch of PHP that the bug affects (only green branches on
|
||||
[the supported version page](https://www.php.net/supported-versions.php) are
|
||||
|
@ -137,8 +131,12 @@ should be credited, the `Co-authored-by` tag in the commit message may be used.
|
|||
|
||||
## Writing documentation
|
||||
|
||||
Editing the manual is done by checking out the XML sources using Git and editing
|
||||
and building it [per the instructions on the documentation site](http://doc.php.net/tutorial/).
|
||||
There are two ways to contribute to the PHP manual. You can edit the manual and
|
||||
send patches anonymously via [the online editor](https://edit.php.net/), or you
|
||||
can check the XML source out from Subversion and edit that and build it
|
||||
[per the instructions on the documentation site](http://doc.php.net/tutorial/).
|
||||
Patches created that way should be sent to the
|
||||
[documentation mailing list](mailto:phpdoc@lists.php.net).
|
||||
|
||||
## Getting help
|
||||
|
||||
|
@ -208,9 +206,6 @@ locations.
|
|||
├─ libmbfl/ # Forked and maintained in php-src
|
||||
├─ unicode_data.h # Generated by `ext/mbstring/ucgendat/ucgendat.php`
|
||||
└─ ...
|
||||
└─ opcache/
|
||||
└─ jit/
|
||||
└─ ir/ # Bundled part of IR framework https://github.com/dstogov/ir
|
||||
└─ pcre/
|
||||
├─ pcre2lib/ # https://www.pcre.org/
|
||||
└─ ...
|
||||
|
@ -244,6 +239,7 @@ locations.
|
|||
└─ ...
|
||||
├─ scripts/ # php-config, phpize and internal development scripts
|
||||
├─ tests/ # Core features tests
|
||||
├─ travis/ # Travis CI service files
|
||||
└─ win32/ # Windows build system files
|
||||
├─ cp_enc_map.c # Generated by `win32/cp_enc_map_gen.exe`
|
||||
└─ ...
|
||||
|
@ -356,12 +352,10 @@ Currently, we have the following branches in use:
|
|||
|
||||
| Branch | |
|
||||
| --------- | --------- |
|
||||
| master | Active development branch for PHP 8.5, which is open for backwards incompatible changes and major internal API changes. |
|
||||
| PHP-8.4 | Is used to release the PHP 8.4.x series. This is a current stable version and is open for bugfixes only. |
|
||||
| PHP-8.3 | Is used to release the PHP 8.3.x series. This is a current stable version and is open for bugfixes only. |
|
||||
| PHP-8.2 | Is used to release the PHP 8.2.x series. This is an old stable version and is open for security fixes only. |
|
||||
| PHP-8.1 | Is used to release the PHP 8.1.x series. This is an old stable version and is open for security fixes only. |
|
||||
| PHP-8.0 | This branch is closed. |
|
||||
| master | Active development branch for PHP 8.3, which is open for backwards incompatible changes and major internal API changes. |
|
||||
| PHP-8.2 | Is used to release the PHP 8.2.x series. This is a current stable version and is open for bugfixes only. |
|
||||
| PHP-8.1 | Is used to release the PHP 8.1.x series. This is a current stable version and is open for bugfixes only. |
|
||||
| PHP-8.0 | Is used to release the PHP 8.0.x series. This is an old stable version and is open for security fixes only. |
|
||||
| PHP-7.4 | This branch is closed. |
|
||||
| PHP-7.3 | This branch is closed. |
|
||||
| PHP-7.2 | This branch is closed. |
|
||||
|
|
53
EXTENSIONS
53
EXTENSIONS
|
@ -93,9 +93,14 @@ MAINTENANCE: Maintained
|
|||
STATUS: Working
|
||||
SINCE: 5.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: oci8
|
||||
PRIMARY MAINTAINER: Christopher Jones <sixd@php.net> (2007 - 2017)
|
||||
Antony Dovgal <tony2001@php.net> (2003 - 2009)
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: odbc
|
||||
PRIMARY MAINTAINER: Daniel R. Kalowsky <kalowsky@php.net> (2000 - 2004)
|
||||
Calvin Buckley <calvin@cmpct.info> (2024 - )
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
COMMENT: Working
|
||||
|
@ -129,8 +134,14 @@ STATUS: Working
|
|||
SINCE: 5.1
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pdo_odbc
|
||||
PRIMARY MAINTAINER: Calvin Buckley <calvin@cmpct.info> (2024 - )
|
||||
MAINTENANCE: Maintained
|
||||
PRIMARY MAINTAINER: Unknown
|
||||
MAINTENANCE: Odd fixes
|
||||
STATUS: Working
|
||||
SINCE: 5.1
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pdo_oci
|
||||
PRIMARY MAINTAINER: Christopher Jones <sixd@php.net> (2007 - 2017)
|
||||
MAINTENANCE: Odd fixes
|
||||
STATUS: Working
|
||||
SINCE: 5.1
|
||||
-------------------------------------------------------------------------------
|
||||
|
@ -195,13 +206,6 @@ PRIMARY MAINTAINER: Thies C. Arntzen <thies@thieso.net> (1999 - 2002)
|
|||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: lexbor
|
||||
PRIMARY MAINTAINER: Niels Dossche <nielsdos@php.net> (2025 - 2025)
|
||||
Mate Kocsis <kocsismate@php.net> (2025 - 2025)
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 8.5
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: libxml
|
||||
PRIMARY MAINTAINER: Rob Richards <rrichards@php.net> (2003 - 2009)
|
||||
Christian Stocker <chregu@php.net> (2004 - 2011)
|
||||
|
@ -238,7 +242,6 @@ SINCE: 5.0
|
|||
-------------------------------------------------------------------------------
|
||||
EXTENSION: bcmath
|
||||
PRIMARY MAINTAINER: Andi Gutmans <andi@php.net> (2000 - 2004)
|
||||
Saki Takamachi <saki@php.net> (2024 - 2025)
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
|
@ -355,6 +358,14 @@ MAINTENANCE: Maintained
|
|||
STATUS: Working
|
||||
SINCE: 5.3
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: imap
|
||||
PRIMARY MAINTAINER: Chuck Hagenbuch <chuck@horde.org> (1999 - 2004)
|
||||
Ilia Alshanetsky <iliaa@php.net> (2002 - 2010)
|
||||
Pierre-Alain Joye <pajoye@php.net> (2008 - 2010)
|
||||
Bishop Bettini <bishop@php.net> (2018 - 2019)
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: json
|
||||
PRIMARY MAINTAINER: Jakub Zelenka <bukka@php.net> (2014 - 2018)
|
||||
MAINTENANCE: Maintained
|
||||
|
@ -372,8 +383,7 @@ STATUS: Working
|
|||
EXTENSION: mbstring
|
||||
PRIMARY MAINTAINER: Rui Hirokawa <hirokawa@php.net> (2001 - 2013)
|
||||
Nikita Popov <nikic@php.net> (2017 - 2020)
|
||||
Alex Dowad <alexinbeijing@gmail.com> (2021 - 2024)
|
||||
Yuya Hamada <youkidearitai@gmail.com> (2024 - 2024)
|
||||
Alex Dowad <alexinbeijing@gmail.com> (2021 - 2022)
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
|
@ -418,9 +428,15 @@ PRIMARY MAINTAINER: Kristian Köhntopp <kris@koehntopp.de> (2000 - 2000)
|
|||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: pspell
|
||||
PRIMARY MAINTAINER: Vlad Krupin <phpdevel@echospace.com> (2000 - 2004)
|
||||
MAINTENANCE: Unknown
|
||||
STATUS: Working
|
||||
SINCE: 4.0.2
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: random
|
||||
PRIMARY MAINTAINER Go Kudo <zeriyoshi@php.net> (2022 - 2024)
|
||||
Tim Düsterhus <timwolla@php.net> (2022 - 2025)
|
||||
PRIMARY MAINTAINER Go Kudo <zeriyoshi@php.net> (2022 - 2022)
|
||||
Tim Düsterhus <timwolla@php.net> (2022 - 2023)
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 8.2.0
|
||||
|
@ -434,7 +450,6 @@ EXTENSION: reflection
|
|||
PRIMARY MAINTAINER: Marcus Börger <helly@php.net> (2003 - 2009)
|
||||
Johannes Schlüter <johannes@php.net> (2006 - 2014)
|
||||
Nikita Popov <nikic@php.net> (2019 - 2020)
|
||||
Daniel Scherzer <daniel.e.scherzer@gmail.com> (2025 - 2025)
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
|
@ -504,12 +519,6 @@ PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net> (2002 - 2002)
|
|||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: uri
|
||||
PRIMARY MAINTAINER Máté Kocsis <kocsismate@php.net> (2025 - 2025)
|
||||
MAINTENANCE: Maintained
|
||||
STATUS: Working
|
||||
SINCE: 8.5.0
|
||||
-------------------------------------------------------------------------------
|
||||
EXTENSION: zip
|
||||
PRIMARY MAINTAINER: Pierre-Alain Joye <pajoye@php.net> (2006 - 2011)
|
||||
Remi Collet <remi@php.net> (2013-2020)
|
||||
|
|
|
@ -17,9 +17,7 @@
|
|||
17. ext/mbstring/ucgendat portions based on the ucgendat.c from the OpenLDAP
|
||||
18. avifinfo (ext/standard/libavifinfo) see ext/standard/libavifinfo/LICENSE
|
||||
19. xxHash (ext/hash/xxhash)
|
||||
20. Lexbor (ext/lexbor/lexbor) see ext/lexbor/LICENSE
|
||||
21. Portions of libcperciva (ext/hash/hash_sha_{ni,sse2}.c) see the header in the source file
|
||||
22. uriparser (ext/uri/uriparser) see ext/uri/uriparser/COPYING
|
||||
|
||||
|
||||
3. pcre2lib (ext/pcre)
|
||||
|
||||
|
|
52
README.md
52
README.md
|
@ -1,5 +1,5 @@
|
|||
<div align="center">
|
||||
<a href="https://www.php.net">
|
||||
<a href="https://php.net">
|
||||
<img
|
||||
alt="PHP"
|
||||
src="https://www.php.net/images/logos/new-php-logo.svg"
|
||||
|
@ -15,11 +15,12 @@ blog to the most popular websites in the world. PHP is distributed under the
|
|||
[PHP License v3.01](LICENSE).
|
||||
|
||||
[](https://github.com/php/php-src/actions/workflows/push.yml)
|
||||
[](https://issues.oss-fuzz.com/issues?q=project:php)
|
||||
[](https://travis-ci.com/github/php/php-src)
|
||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:php)
|
||||
|
||||
## Documentation
|
||||
|
||||
The PHP manual is available at [php.net/docs](https://www.php.net/docs).
|
||||
The PHP manual is available at [php.net/docs](https://php.net/docs).
|
||||
|
||||
## Installation
|
||||
|
||||
|
@ -31,7 +32,7 @@ For Windows, the PHP binaries can be obtained from
|
|||
[windows.php.net](https://windows.php.net). After extracting the archive the
|
||||
`*.exe` files are ready to use.
|
||||
|
||||
For other systems, see the [installation chapter](https://www.php.net/install).
|
||||
For other systems, see the [installation chapter](https://php.net/install).
|
||||
|
||||
### Building PHP source code
|
||||
|
||||
|
@ -42,50 +43,28 @@ a default build, you will additionally need libxml2 and libsqlite3.
|
|||
|
||||
On Ubuntu, you can install these using:
|
||||
|
||||
```shell
|
||||
sudo apt install -y pkg-config build-essential autoconf bison re2c libxml2-dev libsqlite3-dev
|
||||
```
|
||||
sudo apt install -y pkg-config build-essential autoconf bison re2c \
|
||||
libxml2-dev libsqlite3-dev
|
||||
|
||||
On Fedora, you can install these using:
|
||||
|
||||
```shell
|
||||
sudo dnf install re2c bison autoconf make libtool ccache libxml2-devel sqlite-devel
|
||||
```
|
||||
|
||||
On MacOS, you can install these using `brew`:
|
||||
|
||||
```shell
|
||||
brew install autoconf bison re2c iconv libxml2 sqlite
|
||||
```
|
||||
|
||||
or with `MacPorts`:
|
||||
|
||||
```shell
|
||||
sudo port install autoconf bison re2c libiconv libxml2 sqlite3
|
||||
```
|
||||
|
||||
Generate configure:
|
||||
|
||||
```shell
|
||||
./buildconf
|
||||
```
|
||||
|
||||
Configure your build. `--enable-debug` is recommended for development, see
|
||||
`./configure --help` for a full list of options.
|
||||
|
||||
```shell
|
||||
# For development
|
||||
./configure --enable-debug
|
||||
# For production
|
||||
./configure
|
||||
```
|
||||
|
||||
Build PHP. To speed up the build, specify the maximum number of jobs using the
|
||||
`-j` argument:
|
||||
Build PHP. To speed up the build, specify the maximum number of jobs using `-j`:
|
||||
|
||||
```shell
|
||||
make -j4
|
||||
```
|
||||
|
||||
The number of jobs should usually match the number of available cores, which
|
||||
can be determined using `nproc`.
|
||||
|
@ -96,21 +75,13 @@ PHP ships with an extensive test suite, the command `make test` is used after
|
|||
successful compilation of the sources to run this test suite.
|
||||
|
||||
It is possible to run tests using multiple cores by setting `-jN` in
|
||||
`TEST_PHP_ARGS` or `TESTS`:
|
||||
`TEST_PHP_ARGS`:
|
||||
|
||||
```shell
|
||||
make TEST_PHP_ARGS=-j4 test
|
||||
```
|
||||
|
||||
Shall run `make test` with a maximum of 4 concurrent jobs: Generally the maximum
|
||||
number of jobs should not exceed the number of cores available.
|
||||
|
||||
Use the `TEST_PHP_ARGS` or `TESTS` variable to test only specific directories:
|
||||
|
||||
```shell
|
||||
make TESTS=tests/lang/ test
|
||||
```
|
||||
|
||||
The [qa.php.net](https://qa.php.net) site provides more detailed info about
|
||||
testing and quality assurance.
|
||||
|
||||
|
@ -118,9 +89,7 @@ testing and quality assurance.
|
|||
|
||||
After a successful build (and test), PHP may be installed with:
|
||||
|
||||
```shell
|
||||
make install
|
||||
```
|
||||
|
||||
Depending on your permissions and prefix, `make install` may need super user
|
||||
permissions.
|
||||
|
@ -162,11 +131,10 @@ contribute:
|
|||
|
||||
- [Contributing to PHP](/CONTRIBUTING.md)
|
||||
- [PHP coding standards](/CODING_STANDARDS.md)
|
||||
- [Internal documentation](https://php.github.io/php-src/)
|
||||
- [Mailing list rules](/docs/mailinglist-rules.md)
|
||||
- [PHP release process](/docs/release-process.md)
|
||||
|
||||
## Credits
|
||||
|
||||
For the list of people who've put work into PHP, please see the
|
||||
[PHP credits page](https://www.php.net/credits.php).
|
||||
[PHP credits page](https://php.net/credits.php).
|
||||
|
|
27
TSRM/TSRM.c
27
TSRM/TSRM.c
|
@ -576,27 +576,6 @@ void ts_free_id(ts_rsrc_id id)
|
|||
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully freed resource id %d", id));
|
||||
}/*}}}*/
|
||||
|
||||
TSRM_API void ts_apply_for_id(ts_rsrc_id id, void (*cb)(void *))
|
||||
{
|
||||
int rsrc_id = TSRM_UNSHUFFLE_RSRC_ID(id);
|
||||
|
||||
tsrm_mutex_lock(tsmm_mutex);
|
||||
|
||||
if (tsrm_tls_table && resource_types_table) {
|
||||
for (int i = 0; i < tsrm_tls_table_size; i++) {
|
||||
tsrm_tls_entry *p = tsrm_tls_table[i];
|
||||
|
||||
while (p) {
|
||||
if (p->count > rsrc_id && p->storage[rsrc_id]) {
|
||||
cb(p->storage[rsrc_id]);
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tsrm_mutex_unlock(tsmm_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility Functions
|
||||
|
@ -777,16 +756,14 @@ TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void)
|
|||
// TODO: Implement support for fast JIT ZTS code ???
|
||||
return 0;
|
||||
#elif defined(__x86_64__) && defined(__GNUC__) && !defined(__FreeBSD__) && \
|
||||
!defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) && \
|
||||
!defined(__HAIKU__) && !defined(__CYGWIN__)
|
||||
!defined(__OpenBSD__) && !defined(__MUSL__) && !defined(__HAIKU__)
|
||||
size_t ret;
|
||||
|
||||
asm ("movq _tsrm_ls_cache@gottpoff(%%rip),%0"
|
||||
: "=r" (ret));
|
||||
return ret;
|
||||
#elif defined(__i386__) && defined(__GNUC__) && !defined(__FreeBSD__) && \
|
||||
!defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) && \
|
||||
!defined(__HAIKU__) && !defined(__CYGWIN__)
|
||||
!defined(__OpenBSD__) && !defined(__MUSL__) && !defined(__HAIKU__)
|
||||
size_t ret;
|
||||
|
||||
asm ("leal _tsrm_ls_cache@ntpoff,%0"
|
||||
|
|
11
TSRM/TSRM.h
11
TSRM/TSRM.h
|
@ -13,11 +13,11 @@
|
|||
#ifndef TSRM_H
|
||||
#define TSRM_H
|
||||
|
||||
#if !defined(__CYGWIN__) && defined(_WIN32)
|
||||
#if !defined(__CYGWIN__) && defined(WIN32)
|
||||
# define TSRM_WIN32
|
||||
# include <Zend/zend_config.w32.h>
|
||||
# include "Zend/zend_config.w32.h"
|
||||
#else
|
||||
# include <main/php_config.h>
|
||||
# include "main/php_config.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
@ -104,9 +104,6 @@ TSRM_API void ts_free_thread(void);
|
|||
/* deallocates all occurrences of a given id */
|
||||
TSRM_API void ts_free_id(ts_rsrc_id id);
|
||||
|
||||
/* Runs a callback on all resources of the given id.
|
||||
* The caller is responsible for ensuring the underlying resources don't data-race. */
|
||||
TSRM_API void ts_apply_for_id(ts_rsrc_id id, void (*cb)(void *));
|
||||
|
||||
/* Debug support */
|
||||
#define TSRM_ERROR_LEVEL_ERROR 1
|
||||
|
@ -152,7 +149,7 @@ TSRM_API bool tsrm_is_managed_thread(void);
|
|||
# define __has_attribute(x) 0
|
||||
#endif
|
||||
|
||||
#if !__has_attribute(tls_model) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__MUSL__) || defined(__HAIKU__)
|
||||
#if !__has_attribute(tls_model) || defined(__FreeBSD__) || defined(__MUSL__) || defined(__HAIKU__)
|
||||
# define TSRM_TLS_MODEL_ATTR
|
||||
# define TSRM_TLS_MODEL_DEFAULT
|
||||
#elif __PIC__
|
||||
|
|
|
@ -31,6 +31,12 @@ dnl
|
|||
dnl Set some magic defines to achieve POSIX threads conformance.
|
||||
dnl
|
||||
AC_DEFUN([PTHREADS_FLAGS],[
|
||||
if test -z "$host_alias" && test -n "$host"; then
|
||||
host_alias=$host
|
||||
fi
|
||||
if test -z "$host_alias"; then
|
||||
AC_MSG_ERROR(host_alias is not set. Make sure to run config.guess)
|
||||
fi
|
||||
case $host_alias in
|
||||
*solaris*)
|
||||
PTHREAD_FLAGS="-D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT";;
|
||||
|
@ -40,6 +46,8 @@ AC_DEFUN([PTHREADS_FLAGS],[
|
|||
PTHREAD_FLAGS=-D_REENTRANT;;
|
||||
*aix*)
|
||||
PTHREAD_FLAGS=-D_THREAD_SAFE;;
|
||||
*irix*)
|
||||
PTHREAD_FLAGS=-D_POSIX_THREAD_SAFE_FUNCTIONS;;
|
||||
*hpux*)
|
||||
PTHREAD_FLAGS=-D_REENTRANT;;
|
||||
*sco*)
|
||||
|
@ -126,7 +134,7 @@ if test "$pthreads_working" != "yes"; then
|
|||
fi
|
||||
])
|
||||
|
||||
if test "x$ac_cv_pthreads_cflags" != "x" || test "x$ac_cv_pthreads_lib" != "x"; then
|
||||
if test "x$ac_cv_pthreads_cflags" != "x" -o "x$ac_cv_pthreads_lib" != "x"; then
|
||||
pthreads_working="yes"
|
||||
fi
|
||||
])
|
||||
|
|
17
TSRM/tsrm.m4
Normal file
17
TSRM/tsrm.m4
Normal file
|
@ -0,0 +1,17 @@
|
|||
dnl This file contains TSRM specific autoconf macros.
|
||||
|
||||
dnl
|
||||
dnl TSRM_CHECK_PTHREADS
|
||||
dnl
|
||||
AC_DEFUN([TSRM_CHECK_PTHREADS],[
|
||||
PTHREADS_CHECK
|
||||
|
||||
if test "$pthreads_working" != "yes"; then
|
||||
AC_MSG_ERROR(Your system seems to lack POSIX threads.)
|
||||
fi
|
||||
|
||||
AC_DEFINE(PTHREADS, 1, Whether to use Pthreads)
|
||||
|
||||
AC_MSG_CHECKING(for POSIX threads)
|
||||
AC_MSG_RESULT(yes)
|
||||
])
|
|
@ -481,13 +481,12 @@ TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
size_t cmd_buffer_size = strlen(command) + strlen(TWG(comspec)) + sizeof(" /s /c ") + 2;
|
||||
cmd = malloc(cmd_buffer_size);
|
||||
cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /s /c ")+2);
|
||||
if (!cmd) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(cmd, cmd_buffer_size, "%s /s /c \"%s\"", TWG(comspec), command);
|
||||
sprintf(cmd, "%s /s /c \"%s\"", TWG(comspec), command);
|
||||
cmdw = php_win32_cp_any_to_w(cmd);
|
||||
if (!cmdw) {
|
||||
free(cmd);
|
||||
|
@ -636,7 +635,7 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
|
|||
{/*{{{*/
|
||||
shm_pair *shm;
|
||||
char shm_segment[sizeof(SEGMENT_PREFIX INT_MIN_AS_STRING)];
|
||||
HANDLE shm_handle = NULL;
|
||||
HANDLE shm_handle = NULL, info_handle = NULL;
|
||||
BOOL created = FALSE;
|
||||
|
||||
if (key != IPC_PRIVATE) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
PHP 8.5 INTERNALS UPGRADE NOTES
|
||||
PHP 8.3 INTERNALS UPGRADE NOTES
|
||||
|
||||
1. Internal API changes
|
||||
|
||||
|
@ -14,158 +14,157 @@ PHP 8.5 INTERNALS UPGRADE NOTES
|
|||
1. Internal API changes
|
||||
========================
|
||||
|
||||
- Core
|
||||
. PG(arg_separator).input and PG(arg_separator).output are now `zend_string*`
|
||||
instead of `char*`.
|
||||
. DL_LOAD now doesn't use RTLD_DEEPBIND deepbind anymore on platforms
|
||||
where dlmopen with LM_ID_NEWLM is available:
|
||||
this means shared library symbol isolation (if needed) must be enabled on
|
||||
the user side when requiring libphp.so, by using dlmopen with LM_ID_NEWLM
|
||||
instead of dlopen.
|
||||
RTLD_DEEPBIND is still enabled when the Apache SAPI is in use.
|
||||
. The ptr field of the php_stream_notifier struct is now a void* instead
|
||||
of a zval. If the zval was used to store IS_PTR values only, the
|
||||
extra layer of indirection can be removed. In other cases a zval can
|
||||
be heap-allocated and stored in the pointer as a minimal change to keep
|
||||
compatibility.
|
||||
|
||||
- Hash
|
||||
. Hash functions now use proper hash_spec_result enum for return values
|
||||
instead of using SUCCESS and FAILURE.
|
||||
|
||||
- Zend
|
||||
. Added zend_safe_assign_to_variable_noref() function to safely assign
|
||||
a value to a non-reference zval.
|
||||
. Added zval_ptr_safe_dtor() to safely destroy a zval when a destructor
|
||||
could interfere.
|
||||
. zend_get_callable_name() now returns the name of the underlying function
|
||||
for fake closures.
|
||||
. Added smart_string_append_printf() matching smart_str_append_printf() for
|
||||
char* instead of zend_string*-based smart strings.
|
||||
. Added php_build_provider() to retrieve the value of PHP_BUILD_PROVIDER at
|
||||
runtime.
|
||||
. Removed the cache_slot argument of zend_check_user_type_slow() because
|
||||
now it only relies on the CE cache.
|
||||
. Added ZEND_NONSTRING attribute macro for character arrays that do not
|
||||
represent strings. This allows to silence the GCC 15.x
|
||||
`-Wunterminated-string-initialization` warning.
|
||||
. Added the zend_update_exception_properties() function for instantiating
|
||||
Exception child classes. It updates the $message, $code, and $previous
|
||||
properties.
|
||||
. zend_exception_get_default() was removed, use zend_ce_exception directly.
|
||||
. zend_get_error_exception() was removed, use zend_ce_error_exception
|
||||
directly.
|
||||
. ZEND_IS_XDIGIT() macro was removed because it was unused and its name
|
||||
did not match its actual behavior.
|
||||
. The following zend_string-related legacy aliases were removed:
|
||||
* IS_INTERNED() - use ZSTR_IS_INTERNED()
|
||||
* STR_EMPTY_ALLOC() - use ZSTR_EMPTY_ALLOC()
|
||||
* _STR_HEADER_SIZE - use _ZSTR_HEADER_SIZE
|
||||
* STR_ALLOCA_ALLOC() - use ZSTR_ALLOCA_ALLOC()
|
||||
* STR_ALLOCA_INIT() - use ZSTR_ALLOCA_INIT()
|
||||
* STR_ALLOCA_FREE() - use ZSTR_ALLOCA_FREE()
|
||||
. zend_register_constant() now returns a pointer to the added constant
|
||||
on success and NULL on failure instead of SUCCESS/FAILURE.
|
||||
The specialized registration methods that previously had void returns
|
||||
also return pointers to the added constants:
|
||||
* zend_register_bool_constant()
|
||||
* zend_register_null_constant()
|
||||
* zend_register_long_constant()
|
||||
* zend_register_double_constant()
|
||||
* zend_register_string_constant()
|
||||
* zend_register_stringl_constant()
|
||||
. EG(fake_scope) now is a _const_ zend_class_entry*.
|
||||
. zend_begin_record_errors() or EG(record_errors)=true cause errors to be
|
||||
delayed. Before, errors would be recorded but not delayed.
|
||||
. zend_mm_refresh_key_child() must be called on any zend_mm_heap inherited
|
||||
from the parent process after a fork().
|
||||
. HASH_KEY_IS_* constants have been moved in the zend_hash_key_type enum.
|
||||
|
||||
- standard
|
||||
. ext/standard/php_smart_string.h and ext/standard/php_smart_string_public.h
|
||||
were removed. Use the corresponding headers in Zend/ instead.
|
||||
* zend_class_entry now possesses a default_object_handlers field, which
|
||||
provides a default object handler when create_object() is not overriding it.
|
||||
* Custom Fiber implementations have to initialize EG(stack_limit) and
|
||||
EG(stack_base).
|
||||
* EG(opline_before_exception) may now be null if the VM throws an exception
|
||||
before executing any opline.
|
||||
* Many C header files have been cleaned up and include dependencies
|
||||
have been reduced. Many headers which used to be always included by
|
||||
Zend headers (e.g. "errno.h") are no longer implied, and this may
|
||||
break the build of third-party extensions which relied on this
|
||||
implementation detail. Those extensions may need to add the missing
|
||||
#include lines.
|
||||
* Since version 8, PHP requires a C99 compiler. Configure-time checks
|
||||
for C99 features have been removed and therefore macro definitions
|
||||
from php_config.h have disappeared. Do not use those feature
|
||||
macros.
|
||||
* Internal class aliases created during request time can now exist in
|
||||
the class table. zend_register_class_alias_ex() will not increase
|
||||
the refcount for class aliases and the cleanup function takes this
|
||||
into account.
|
||||
* The return types of the following functions have been changed from
|
||||
`bool` to `zend_result`:
|
||||
- zend_fiber_init_context()
|
||||
* The fast_add_function() has been removed, use add_function() that will
|
||||
call the static inline add_function_fast() instead.
|
||||
* The order of members of zend_op_array, zend_ssa_var, zend_ssa_var_info,
|
||||
zend_executor_globals and php_core_globals have changed to improve
|
||||
struct packing which reduces their size.
|
||||
* Many calls to zend_assign_to_variable have been replaced with
|
||||
zend_assign_to_variable_ex which allows delaying the releasing of the old
|
||||
variable value. This avoids side-effects through destructors between the
|
||||
assignment of the variable and the assignment to the result zval in the VM
|
||||
(i.e. it may free the new value). See GH-10168 for details.
|
||||
* The return types of the following functions were changed from int to
|
||||
zend_result:
|
||||
- open_file_for_scanning
|
||||
- php_rfc1867_callback
|
||||
- virtual_chdir
|
||||
- zend_execute_scripts
|
||||
- zend_get_module_started
|
||||
- zend_handle_undef_args
|
||||
- zend_list_delete
|
||||
- zend_multibyte_parse_encoding_list
|
||||
- zend_multibyte_set_internal_encoding
|
||||
- zend_parse_ini_file
|
||||
- zend_parse_ini_string
|
||||
- zend_set_user_opcode_handler
|
||||
- zend_ssa_inference
|
||||
* Removed unused macros PHP_FNV1_32A_INIT and PHP_FNV1A_64_INIT. See GH-11114.
|
||||
* ext/standard/hrtime.h was moved to Zend/zend_hrtime.h
|
||||
* The prefix of the PHP_HRTIME_ macros was changed to ZEND_HRTIME_
|
||||
* The HRTIME_AVAILABLE macro was renamed to ZEND_HRTIME_AVAILABLE
|
||||
* The php_hrtime_current() function was renamed to zend_hrtime()
|
||||
* _php_stream_dirent now has an extra d_type field that is used to store the
|
||||
directory entry type. This can be used to avoid additional stat calls for
|
||||
types when the type is already known.
|
||||
* The misspelled ZEND_CGG_DIAGNOSTIC_IGNORED_(START|END) macros are deprecated.
|
||||
Use ZEND_DIAGNOSTIC_IGNORED_(START|END) instead. These macros now also support
|
||||
Clang.
|
||||
|
||||
========================
|
||||
2. Build system changes
|
||||
========================
|
||||
|
||||
- Abstract
|
||||
. Preprocessor macro SIZEOF_PTRDIFF_T has been removed.
|
||||
. Preprocessor macro SIZEOF_INTMAX_T has been removed.
|
||||
* PHP_EXTRA_VERSION can be passed to configure script to control custom PHP
|
||||
build versions: ./configure PHP_EXTRA_VERSION="-acme"
|
||||
|
||||
- Windows build system changes
|
||||
. SAPI() and ADD_SOURCES() now support the optional `duplicate_sources`
|
||||
parameter. If truthy, no rules to build the object files are generated.
|
||||
This allows to build additional variants of SAPIs (e.g. a DLL and EXE)
|
||||
without duplicate build rules. It is up to the SAPI maintainers to ensure
|
||||
that appropriate build rules are created.
|
||||
* LDFLAGS are not unset anymore allowing them to be adjusted e.g.
|
||||
LDFLAGS="..." ./configure
|
||||
|
||||
- Unix build system changes
|
||||
. libdir is properly set when --libdir (ex: /usr/lib64) and --with-libdir (ex: lib64)
|
||||
configure options are used to ${libdir}/php (ex: /usr/lib64/php)
|
||||
. PHP_ODBC_CFLAGS, PHP_ODBC_LFLAGS, PHP_ODBC_LIBS, PHP_ODBC_TYPE preprocessor
|
||||
macros defined by ext/odbc are now defined in php_config.h instead of the
|
||||
build-defs.h header.
|
||||
. Autoconf macro AX_CHECK_COMPILE_FLAG updated to serial 11.
|
||||
. Autoconf macro PHP_AP_EXTRACT_VERSION has been removed.
|
||||
. Autoconf macro PHP_BUILD_THREAD_SAFE has been removed (set enable_zts
|
||||
manually).
|
||||
. Autoconf macro PHP_CHECK_SIZEOF is obsolete (use AC_CHECK_SIZEOF).
|
||||
. Autoconf macro PHP_DEF_HAVE has been removed (use AC_DEFINE).
|
||||
. Autoconf macro PHP_OUTPUT has been removed (use AC_CONFIG_FILES).
|
||||
. Autoconf macro PHP_TEST_BUILD has been removed (use AC_* macros).
|
||||
. Preprocessor macro HAVE_PTRDIFF_T has been removed.
|
||||
. Preprocessor macro HAVE_INTMAX_T has been removed.
|
||||
. Preprocessor macro HAVE_SSIZE_T has been removed.
|
||||
. Preprocessor macro SIZEOF_SSIZE_T has been removed.
|
||||
* Removed the HAVE_DEV_URANDOM compile time check. HAVE_DEV_URANDOM will
|
||||
now never be defined. Any checks relying on HAVE_DEV_URANDOM should be
|
||||
removed. Even with HAVE_DEV_URANDOM it was not guaranteed that
|
||||
/dev/urandom is actually available at run time and thus a runtime
|
||||
check needs to happen in all cases.
|
||||
|
||||
========================
|
||||
3. Module changes
|
||||
========================
|
||||
|
||||
- ext/gd
|
||||
. The gdImageScale*() and gdImageRotate*() helpers are now internal in the
|
||||
bundled libgd, like they have been in external libgd as of gd-2.1.1.
|
||||
a. ext/json
|
||||
- A new function php_json_validate_ex has been added to check if the
|
||||
provided C string is valid for the given depth and options.
|
||||
|
||||
- ext/json
|
||||
. php_json_encode_serializable_object() now assumes `EG(active)`,
|
||||
if not a bailout is caused. Therefore a minor BC break exists if the
|
||||
`PHP_JSON_PARTIAL_OUTPUT_ON_ERROR` option is in use.
|
||||
However, this situation is highly unlikely.
|
||||
b. ext/standard
|
||||
- The PHPAPI php_url_encode_hash_ex() function has had its signature change
|
||||
from:
|
||||
PHPAPI void php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
|
||||
const char *num_prefix, size_t num_prefix_len,
|
||||
const char *key_prefix, size_t key_prefix_len,
|
||||
const char *key_suffix, size_t key_suffix_len,
|
||||
zval *type, const char *arg_sep, int enc_type);
|
||||
to:
|
||||
PHPAPI void php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
|
||||
const char *num_prefix, size_t num_prefix_len,
|
||||
const zend_string *key_prefix,
|
||||
zval *type, const zend_string *arg_sep, int enc_type);
|
||||
The change to use zend_string prevent the computation of the arg_sep
|
||||
length at each call. The key_suffix parameter was dropped as it was a
|
||||
constant value and depended on the key_prefix parameter to not be NULL.
|
||||
|
||||
- ext/libxml
|
||||
. The refcount APIs now return an `unsigned int` instead of an `int`.
|
||||
. Removed php_libxml_xmlCheckUTF8(). Use xmlCheckUTF8() from libxml instead.
|
||||
c. ext/mysqlnd
|
||||
- The function mysqlnd_shutdown and its corresponding internal methods
|
||||
mysqlnd_command::shutdown & mysqlnd_conn_data::shutdown have been removed.
|
||||
These functions are deprecated by MySQL in favour of SHUTDOWN SQL statement.
|
||||
|
||||
- ext/pdo
|
||||
. Added `php_pdo_stmt_valid_db_obj_handle()` to check if the database object
|
||||
is still valid. This is useful when a GC cycle is collected and the
|
||||
database object can be destroyed prior to destroying the statement.
|
||||
d. ext/pcre
|
||||
- The function pcre_get_compiled_regex_ex has been removed.
|
||||
Use pcre_get_compiled_regex instead.
|
||||
|
||||
- ext/standard
|
||||
. Added php_url_decode_ex() and php_raw_url_decode_ex() that unlike their
|
||||
non-ex counterparts do not work in-place.
|
||||
. The php_std_date() function has been removed. Use php_format_date() with
|
||||
the "D, d M Y H:i:s \\G\\M\\T" format instead.
|
||||
. Added php_url_encode_to_smart_str() to encode a URL to a smart_str buffer.
|
||||
. The functionality of getimagesize(), image_type_to_mime_type(),
|
||||
and image_type_to_extension() is now extensible using the internal APIs
|
||||
php_image_register_handler() and php_image_unregister_handler() in
|
||||
php_image.h.
|
||||
e. ext/spl
|
||||
- The PHPAPI spl_iterator_apply() function now returns zend_result instead of int.
|
||||
There are no functional changes.
|
||||
- The field _spl_filesystem_object->is_recursive has been removed.
|
||||
|
||||
f. ext/dom
|
||||
- A new function dom_get_doc_props_read_only() is added to gather the document
|
||||
properties in a read-only way. This function avoids allocation when there are
|
||||
no document properties changed yet.
|
||||
- The node list returned by DOMNode::getElementsByTagName() and
|
||||
DOMNode::getElementsByTagNameNS() now caches the length and the last requested item.
|
||||
This means that the length and the last requested item are not recalculated
|
||||
when the node list is iterated over multiple times.
|
||||
If you do not use the internal PHP dom APIs to modify the document, you need to
|
||||
manually invalidate the cache using php_libxml_invalidate_node_list_cache_from_doc().
|
||||
Furthermore, the following internal APIs were added to handle the cache:
|
||||
. php_dom_is_cache_tag_stale_from_doc_ptr()
|
||||
. php_dom_is_cache_tag_stale_from_node()
|
||||
. php_dom_mark_cache_tag_up_to_date_from_node()
|
||||
- The function dom_get_elements_by_tag_name_ns_raw() has an additional parameter to indicate
|
||||
the base node of the node list. This function also no longer accepts -1 as the index argument.
|
||||
- The function dom_namednode_iter() has additional arguments to avoid recomputing the length of
|
||||
the strings.
|
||||
- The functions dom_parent_node_prepend(), dom_parent_node_append(), dom_parent_node_after(), and
|
||||
dom_parent_node_before() now use an uint32_t argument for the number of nodes instead of int.
|
||||
- There is now a helper function php_dom_get_content_into_zval() to get the contents of a node.
|
||||
This avoids allocation if possible.
|
||||
- The function dom_set_old_ns() has been moved into ext/libxml as php_libxml_set_old_ns() and
|
||||
is now publicly exposed as an API.
|
||||
|
||||
g. ext/libxml
|
||||
- Two new functions: php_libxml_invalidate_node_list_cache_from_doc() and
|
||||
php_libxml_invalidate_node_list_cache() were added to invalidate the cache of a node list.
|
||||
|
||||
========================
|
||||
4. OpCode changes
|
||||
========================
|
||||
|
||||
* New ZEND_DECLARE_ATTRIBUTED_CONST is used when a global constant is declared
|
||||
with `const` and has attributes; this opcode is used *instead* of the
|
||||
ZEND_DECLARE_CONST, and in addition to the name of the constant and the
|
||||
value to use, has a ZEND_OP_DATA with a pointer to the compiled attributes.
|
||||
|
||||
========================
|
||||
5. SAPI changes
|
||||
========================
|
||||
|
||||
- SAPIs must now call php_child_init() after a fork. If php-src code was
|
||||
executed in other threads than the one initiating the fork,
|
||||
refresh_memory_manager() must be called in every such thread.
|
||||
* SAPIs that may execute in alternative stacks have to set EG(stack_limit) and
|
||||
EG(stack_base)
|
||||
|
|
|
@ -6,7 +6,7 @@ $(builddir)/zend_language_scanner.lo: $(srcdir)/zend_language_parser.h
|
|||
$(builddir)/zend_ini_scanner.lo: $(srcdir)/zend_ini_parser.h
|
||||
|
||||
$(srcdir)/zend_language_scanner.c $(srcdir)/zend_language_scanner_defs.h: $(srcdir)/zend_language_scanner.l
|
||||
@(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt Zend/zend_language_scanner_defs.h -oZend/zend_language_scanner.c Zend/zend_language_scanner.l)
|
||||
@(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt Zend/zend_language_scanner_defs.h -oZend/zend_language_scanner.c Zend/zend_language_scanner.l)
|
||||
|
||||
$(srcdir)/zend_language_parser.h: $(srcdir)/zend_language_parser.c
|
||||
$(srcdir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y
|
||||
|
@ -23,10 +23,10 @@ $(srcdir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y
|
|||
|
||||
$(srcdir)/zend_ini_parser.h: $(srcdir)/zend_ini_parser.c
|
||||
$(srcdir)/zend_ini_parser.c: $(srcdir)/zend_ini_parser.y
|
||||
@$(YACC) $(YFLAGS) -v -d $(srcdir)/zend_ini_parser.y -o $@
|
||||
$(YACC) $(YFLAGS) -v -d $(srcdir)/zend_ini_parser.y -o $@
|
||||
|
||||
$(srcdir)/zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l
|
||||
@(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt Zend/zend_ini_scanner_defs.h -oZend/zend_ini_scanner.c Zend/zend_ini_scanner.l)
|
||||
@(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt Zend/zend_ini_scanner_defs.h -oZend/zend_ini_scanner.c Zend/zend_ini_scanner.l)
|
||||
|
||||
# Use an intermediate target to indicate that zend_vm_gen.php produces both files
|
||||
# at the same time, rather than the same recipe applying for two different targets.
|
||||
|
|
|
@ -274,9 +274,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
|
|||
* If it's not local, then the other blocks successors must also eventually either FREE or consume the temporary,
|
||||
* hence removing the temporary is not safe in the general case, especially when other consumers are not FREE.
|
||||
* A FREE may not be removed without also removing the source's result, because otherwise that would cause a memory leak. */
|
||||
if (opline->extended_value == ZEND_FREE_VOID_CAST) {
|
||||
/* Keep the ZEND_FREE opcode alive. */
|
||||
} else if (opline->op1_type == IS_TMP_VAR) {
|
||||
if (opline->op1_type == IS_TMP_VAR) {
|
||||
src = VAR_SOURCE(opline->op1);
|
||||
if (src) {
|
||||
switch (src->opcode) {
|
||||
|
@ -420,14 +418,6 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
|
|||
}
|
||||
break;
|
||||
|
||||
case ZEND_EXT_STMT:
|
||||
if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
|
||||
/* Variable will be deleted later by FREE, so we can't optimize it */
|
||||
Tsource[VAR_NUM(opline->op1.var)] = NULL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ZEND_CASE:
|
||||
case ZEND_CASE_STRICT:
|
||||
case ZEND_COPY_TMP:
|
||||
|
@ -478,66 +468,6 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
|
|||
goto optimize_bool;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_IDENTICAL:
|
||||
if (opline->op1_type == IS_CONST &&
|
||||
opline->op2_type == IS_CONST) {
|
||||
goto optimize_constant_binary_op;
|
||||
}
|
||||
|
||||
if (opline->op1_type == IS_CONST &&
|
||||
(Z_TYPE(ZEND_OP1_LITERAL(opline)) <= IS_TRUE && Z_TYPE(ZEND_OP1_LITERAL(opline)) >= IS_NULL)) {
|
||||
/* IS_IDENTICAL(TRUE, T) => TYPE_CHECK(T, TRUE)
|
||||
* IS_IDENTICAL(FALSE, T) => TYPE_CHECK(T, FALSE)
|
||||
* IS_IDENTICAL(NULL, T) => TYPE_CHECK(T, NULL)
|
||||
*/
|
||||
opline->opcode = ZEND_TYPE_CHECK;
|
||||
opline->extended_value = (1 << Z_TYPE(ZEND_OP1_LITERAL(opline)));
|
||||
COPY_NODE(opline->op1, opline->op2);
|
||||
SET_UNUSED(opline->op2);
|
||||
++(*opt_count);
|
||||
goto optimize_type_check;
|
||||
} else if (opline->op2_type == IS_CONST &&
|
||||
(Z_TYPE(ZEND_OP2_LITERAL(opline)) <= IS_TRUE && Z_TYPE(ZEND_OP2_LITERAL(opline)) >= IS_NULL)) {
|
||||
/* IS_IDENTICAL(T, TRUE) => TYPE_CHECK(T, TRUE)
|
||||
* IS_IDENTICAL(T, FALSE) => TYPE_CHECK(T, FALSE)
|
||||
* IS_IDENTICAL(T, NULL) => TYPE_CHECK(T, NULL)
|
||||
*/
|
||||
opline->opcode = ZEND_TYPE_CHECK;
|
||||
opline->extended_value = (1 << Z_TYPE(ZEND_OP2_LITERAL(opline)));
|
||||
SET_UNUSED(opline->op2);
|
||||
++(*opt_count);
|
||||
goto optimize_type_check;
|
||||
}
|
||||
break;
|
||||
case ZEND_TYPE_CHECK:
|
||||
optimize_type_check:
|
||||
if (opline->extended_value == (1 << IS_TRUE) || opline->extended_value == (1 << IS_FALSE)) {
|
||||
if (opline->op1_type == IS_TMP_VAR &&
|
||||
!zend_bitset_in(used_ext, VAR_NUM(opline->op1.var))) {
|
||||
src = VAR_SOURCE(opline->op1);
|
||||
|
||||
if (src) {
|
||||
switch (src->opcode) {
|
||||
case ZEND_BOOL:
|
||||
case ZEND_BOOL_NOT:
|
||||
/* T = BOOL(X) + TYPE_CHECK(T, TRUE) -> BOOL(X), NOP
|
||||
* T = BOOL(X) + TYPE_CHECK(T, FALSE) -> BOOL_NOT(X), NOP
|
||||
* T = BOOL_NOT(X) + TYPE_CHECK(T, TRUE) -> BOOL_NOT(X), NOP
|
||||
* T = BOOL_NOT(X) + TYPE_CHECK(T, FALSE) -> BOOL(X), NOP
|
||||
*/
|
||||
src->opcode =
|
||||
((src->opcode == ZEND_BOOL) == (opline->extended_value == (1 << IS_TRUE))) ?
|
||||
ZEND_BOOL : ZEND_BOOL_NOT;
|
||||
COPY_NODE(src->result, opline->result);
|
||||
SET_VAR_SOURCE(src);
|
||||
MAKE_NOP(opline);
|
||||
++(*opt_count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ZEND_BOOL:
|
||||
case ZEND_BOOL_NOT:
|
||||
|
@ -871,6 +801,7 @@ optimize_type_check:
|
|||
case ZEND_SR:
|
||||
case ZEND_IS_SMALLER:
|
||||
case ZEND_IS_SMALLER_OR_EQUAL:
|
||||
case ZEND_IS_IDENTICAL:
|
||||
case ZEND_IS_NOT_IDENTICAL:
|
||||
case ZEND_BOOL_XOR:
|
||||
case ZEND_BW_OR:
|
||||
|
@ -937,6 +868,7 @@ optimize_const_unary_op:
|
|||
break;
|
||||
|
||||
case ZEND_RETURN:
|
||||
case ZEND_EXIT:
|
||||
if (opline->op1_type == IS_TMP_VAR) {
|
||||
src = VAR_SOURCE(opline->op1);
|
||||
if (src && src->opcode == ZEND_QM_ASSIGN) {
|
||||
|
@ -1085,7 +1017,6 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op
|
|||
case ZEND_ASSERT_CHECK:
|
||||
case ZEND_JMP_NULL:
|
||||
case ZEND_BIND_INIT_STATIC_OR_JMP:
|
||||
case ZEND_JMP_FRAMELESS:
|
||||
ZEND_SET_OP_JMP_ADDR(opline, opline->op2, new_opcodes + blocks[b->successors[0]].start);
|
||||
break;
|
||||
case ZEND_CATCH:
|
||||
|
@ -1289,7 +1220,8 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr
|
|||
target = op_array->opcodes + target_block->start;
|
||||
if ((target->opcode == ZEND_RETURN ||
|
||||
target->opcode == ZEND_RETURN_BY_REF ||
|
||||
target->opcode == ZEND_GENERATOR_RETURN) &&
|
||||
target->opcode == ZEND_GENERATOR_RETURN ||
|
||||
target->opcode == ZEND_EXIT) &&
|
||||
!(op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) {
|
||||
/* JMP L, L: RETURN to immediate RETURN */
|
||||
*last_op = *target;
|
||||
|
|
|
@ -43,6 +43,50 @@ typedef struct _literal_info {
|
|||
info[n].num_related = (related); \
|
||||
} while (0)
|
||||
|
||||
static size_t type_num_classes(const zend_op_array *op_array, uint32_t arg_num)
|
||||
{
|
||||
zend_arg_info *arg_info;
|
||||
if (arg_num > 0) {
|
||||
if (!(op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) {
|
||||
return 0;
|
||||
}
|
||||
if (EXPECTED(arg_num <= op_array->num_args)) {
|
||||
arg_info = &op_array->arg_info[arg_num-1];
|
||||
} else if (UNEXPECTED(op_array->fn_flags & ZEND_ACC_VARIADIC)) {
|
||||
arg_info = &op_array->arg_info[op_array->num_args];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
arg_info = op_array->arg_info - 1;
|
||||
}
|
||||
|
||||
if (ZEND_TYPE_IS_COMPLEX(arg_info->type)) {
|
||||
if (ZEND_TYPE_HAS_LIST(arg_info->type)) {
|
||||
/* Intersection types cannot have nested list types */
|
||||
if (ZEND_TYPE_IS_INTERSECTION(arg_info->type)) {
|
||||
return ZEND_TYPE_LIST(arg_info->type)->num_types;
|
||||
}
|
||||
ZEND_ASSERT(ZEND_TYPE_IS_UNION(arg_info->type));
|
||||
size_t count = 0;
|
||||
zend_type *list_type;
|
||||
|
||||
ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(arg_info->type), list_type) {
|
||||
if (ZEND_TYPE_IS_INTERSECTION(*list_type)) {
|
||||
count += ZEND_TYPE_LIST(*list_type)->num_types;
|
||||
} else {
|
||||
ZEND_ASSERT(!ZEND_TYPE_HAS_LIST(*list_type));
|
||||
count += 1;
|
||||
}
|
||||
} ZEND_TYPE_LIST_FOREACH_END();
|
||||
return count;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t add_static_slot(HashTable *hash,
|
||||
zend_op_array *op_array,
|
||||
uint32_t op1,
|
||||
|
@ -121,7 +165,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
|
|||
HashTable hash;
|
||||
zend_string *key = NULL;
|
||||
void *checkpoint = zend_arena_checkpoint(ctx->arena);
|
||||
int *const_slot, *class_slot, *func_slot, *bind_var_slot, *property_slot, *method_slot, *jmp_slot;
|
||||
int *const_slot, *class_slot, *func_slot, *bind_var_slot, *property_slot, *method_slot;
|
||||
|
||||
if (op_array->last_literal) {
|
||||
info = (literal_info*)zend_arena_calloc(&ctx->arena, op_array->last_literal, sizeof(literal_info));
|
||||
|
@ -131,9 +175,6 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
|
|||
end = opline + op_array->last;
|
||||
while (opline < end) {
|
||||
switch (opline->opcode) {
|
||||
case ZEND_JMP_FRAMELESS:
|
||||
LITERAL_INFO(opline->op1.constant, 1);
|
||||
break;
|
||||
case ZEND_INIT_FCALL_BY_NAME:
|
||||
LITERAL_INFO(opline->op2.constant, 2);
|
||||
break;
|
||||
|
@ -156,9 +197,6 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
|
|||
LITERAL_INFO(opline->op2.constant, 2);
|
||||
}
|
||||
break;
|
||||
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:
|
||||
LITERAL_INFO(opline->op1.constant, 1);
|
||||
break;
|
||||
case ZEND_CATCH:
|
||||
LITERAL_INFO(opline->op1.constant, 2);
|
||||
break;
|
||||
|
@ -439,14 +477,13 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
|
|||
zend_hash_clean(&hash);
|
||||
op_array->last_literal = j;
|
||||
|
||||
const_slot = zend_arena_alloc(&ctx->arena, j * 7 * sizeof(int));
|
||||
memset(const_slot, -1, j * 7 * sizeof(int));
|
||||
const_slot = zend_arena_alloc(&ctx->arena, j * 6 * sizeof(int));
|
||||
memset(const_slot, -1, j * 6 * sizeof(int));
|
||||
class_slot = const_slot + j;
|
||||
func_slot = class_slot + j;
|
||||
bind_var_slot = func_slot + j;
|
||||
property_slot = bind_var_slot + j;
|
||||
method_slot = property_slot + j;
|
||||
jmp_slot = method_slot + j;
|
||||
|
||||
/* Update opcodes to use new literals table */
|
||||
cache_size = zend_op_array_extension_handles * sizeof(void*);
|
||||
|
@ -460,6 +497,26 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
|
|||
opline->op2.constant = map[opline->op2.constant];
|
||||
}
|
||||
switch (opline->opcode) {
|
||||
case ZEND_RECV_INIT:
|
||||
case ZEND_RECV:
|
||||
case ZEND_RECV_VARIADIC:
|
||||
{
|
||||
size_t num_classes = type_num_classes(op_array, opline->op1.num);
|
||||
if (num_classes) {
|
||||
opline->extended_value = cache_size;
|
||||
cache_size += num_classes * sizeof(void *);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ZEND_VERIFY_RETURN_TYPE:
|
||||
{
|
||||
size_t num_classes = type_num_classes(op_array, 0);
|
||||
if (num_classes) {
|
||||
opline->op2.num = cache_size;
|
||||
cache_size += num_classes * sizeof(void *);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ZEND_ASSIGN_STATIC_PROP_OP:
|
||||
if (opline->op1_type == IS_CONST) {
|
||||
// op1 static property
|
||||
|
@ -716,16 +773,6 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
|
|||
opline->extended_value = cache_size;
|
||||
cache_size += sizeof(void *);
|
||||
break;
|
||||
case ZEND_JMP_FRAMELESS:
|
||||
// op1 func
|
||||
if (jmp_slot[opline->op1.constant] >= 0) {
|
||||
opline->extended_value = jmp_slot[opline->op1.constant];
|
||||
} else {
|
||||
opline->extended_value = cache_size;
|
||||
cache_size += sizeof(void *);
|
||||
jmp_slot[opline->op1.constant] = opline->extended_value;
|
||||
}
|
||||
break;
|
||||
case ZEND_SEND_VAL:
|
||||
case ZEND_SEND_VAL_EX:
|
||||
case ZEND_SEND_VAR:
|
||||
|
|
|
@ -80,6 +80,7 @@ static inline bool may_have_side_effects(
|
|||
case ZEND_IS_IDENTICAL:
|
||||
case ZEND_IS_NOT_IDENTICAL:
|
||||
case ZEND_QM_ASSIGN:
|
||||
case ZEND_FREE:
|
||||
case ZEND_FE_FREE:
|
||||
case ZEND_TYPE_CHECK:
|
||||
case ZEND_DEFINED:
|
||||
|
@ -126,8 +127,6 @@ static inline bool may_have_side_effects(
|
|||
case ZEND_ARRAY_KEY_EXISTS:
|
||||
/* No side effects */
|
||||
return 0;
|
||||
case ZEND_FREE:
|
||||
return opline->extended_value == ZEND_FREE_VOID_CAST;
|
||||
case ZEND_ADD_ARRAY_ELEMENT:
|
||||
/* TODO: We can't free two vars. Keep instruction alive. <?php [0, "$a" => "$b"]; */
|
||||
if ((opline->op1_type & (IS_VAR|IS_TMP_VAR)) && (opline->op2_type & (IS_VAR|IS_TMP_VAR))) {
|
||||
|
@ -147,7 +146,6 @@ static inline bool may_have_side_effects(
|
|||
case ZEND_ASSERT_CHECK:
|
||||
case ZEND_JMP_NULL:
|
||||
case ZEND_BIND_INIT_STATIC_OR_JMP:
|
||||
case ZEND_JMP_FRAMELESS:
|
||||
/* For our purposes a jumps and branches are side effects. */
|
||||
return 1;
|
||||
case ZEND_BEGIN_SILENCE:
|
||||
|
@ -169,10 +167,6 @@ static inline bool may_have_side_effects(
|
|||
case ZEND_DO_FCALL_BY_NAME:
|
||||
case ZEND_DO_ICALL:
|
||||
case ZEND_DO_UCALL:
|
||||
case ZEND_FRAMELESS_ICALL_0:
|
||||
case ZEND_FRAMELESS_ICALL_1:
|
||||
case ZEND_FRAMELESS_ICALL_2:
|
||||
case ZEND_FRAMELESS_ICALL_3:
|
||||
/* For now assume all calls have side effects */
|
||||
return 1;
|
||||
case ZEND_RECV:
|
||||
|
|
|
@ -254,7 +254,7 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa, zend_op
|
|||
free_alloca(shiftlist, use_heap);
|
||||
}
|
||||
|
||||
static bool safe_instanceof(const zend_class_entry *ce1, const zend_class_entry *ce2) {
|
||||
static bool safe_instanceof(zend_class_entry *ce1, zend_class_entry *ce2) {
|
||||
if (ce1 == ce2) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -267,9 +267,9 @@ static bool safe_instanceof(const zend_class_entry *ce1, const zend_class_entry
|
|||
|
||||
static inline bool can_elide_list_type(
|
||||
const zend_script *script, const zend_op_array *op_array,
|
||||
const zend_ssa_var_info *use_info, const zend_type type)
|
||||
const zend_ssa_var_info *use_info, zend_type type)
|
||||
{
|
||||
const zend_type *single_type;
|
||||
zend_type *single_type;
|
||||
/* For intersection: result==false is failure, default is success.
|
||||
* For union: result==true is success, default is failure. */
|
||||
bool is_intersection = ZEND_TYPE_IS_INTERSECTION(type);
|
||||
|
@ -280,7 +280,7 @@ static inline bool can_elide_list_type(
|
|||
}
|
||||
if (ZEND_TYPE_HAS_NAME(*single_type)) {
|
||||
zend_string *lcname = zend_string_tolower(ZEND_TYPE_NAME(*single_type));
|
||||
const zend_class_entry *ce = zend_optimizer_get_class_entry(script, op_array, lcname);
|
||||
zend_class_entry *ce = zend_optimizer_get_class_entry(script, op_array, lcname);
|
||||
zend_string_release(lcname);
|
||||
bool result = ce && safe_instanceof(use_info->ce, ce);
|
||||
if (result == !is_intersection) {
|
||||
|
@ -325,19 +325,6 @@ static bool opline_supports_assign_contraction(
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Frameless calls override the return value, but the return value may overlap with the arguments. */
|
||||
switch (opline->opcode) {
|
||||
case ZEND_FRAMELESS_ICALL_3:
|
||||
if ((opline + 1)->op1_type == IS_CV && (opline + 1)->op1.var == cv_var) return 0;
|
||||
ZEND_FALLTHROUGH;
|
||||
case ZEND_FRAMELESS_ICALL_2:
|
||||
if (opline->op2_type == IS_CV && opline->op2.var == cv_var) return 0;
|
||||
ZEND_FALLTHROUGH;
|
||||
case ZEND_FRAMELESS_ICALL_1:
|
||||
if (opline->op1_type == IS_CV && opline->op1.var == cv_var) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (opline->opcode == ZEND_DO_ICALL || opline->opcode == ZEND_DO_UCALL
|
||||
|| opline->opcode == ZEND_DO_FCALL || opline->opcode == ZEND_DO_FCALL_BY_NAME) {
|
||||
/* Function calls may dtor the return value after it has already been written -- allow
|
||||
|
@ -407,28 +394,40 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa)
|
|||
zend_call_info *call_info = func_info->callee_info;
|
||||
|
||||
do {
|
||||
zend_op *op = call_info->caller_init_opline;
|
||||
|
||||
if ((op->opcode == ZEND_FRAMELESS_ICALL_2
|
||||
|| (op->opcode == ZEND_FRAMELESS_ICALL_3 && (op + 1)->op1_type == IS_CONST))
|
||||
if (call_info->caller_call_opline
|
||||
&& call_info->caller_call_opline->opcode == ZEND_DO_ICALL
|
||||
&& call_info->callee_func
|
||||
&& zend_string_equals_literal_ci(call_info->callee_func->common.function_name, "in_array")) {
|
||||
&& zend_string_equals_literal(call_info->callee_func->common.function_name, "in_array")
|
||||
&& (call_info->caller_init_opline->extended_value == 2
|
||||
|| (call_info->caller_init_opline->extended_value == 3
|
||||
&& (call_info->caller_call_opline - 1)->opcode == ZEND_SEND_VAL
|
||||
&& (call_info->caller_call_opline - 1)->op1_type == IS_CONST))) {
|
||||
|
||||
zend_op *send_array;
|
||||
zend_op *send_needly;
|
||||
bool strict = 0;
|
||||
bool has_opdata = op->opcode == ZEND_FRAMELESS_ICALL_3;
|
||||
ZEND_ASSERT(!call_info->is_prototype);
|
||||
|
||||
if (has_opdata) {
|
||||
if (zend_is_true(CT_CONSTANT_EX(op_array, (op + 1)->op1.constant))) {
|
||||
if (call_info->caller_init_opline->extended_value == 2) {
|
||||
send_array = call_info->caller_call_opline - 1;
|
||||
send_needly = call_info->caller_call_opline - 2;
|
||||
} else {
|
||||
if (zend_is_true(CT_CONSTANT_EX(op_array, (call_info->caller_call_opline - 1)->op1.constant))) {
|
||||
strict = 1;
|
||||
}
|
||||
send_array = call_info->caller_call_opline - 2;
|
||||
send_needly = call_info->caller_call_opline - 3;
|
||||
}
|
||||
|
||||
if (op->op2_type == IS_CONST
|
||||
&& Z_TYPE_P(CT_CONSTANT_EX(op_array, op->op2.constant)) == IS_ARRAY) {
|
||||
if (send_array->opcode == ZEND_SEND_VAL
|
||||
&& send_array->op1_type == IS_CONST
|
||||
&& Z_TYPE_P(CT_CONSTANT_EX(op_array, send_array->op1.constant)) == IS_ARRAY
|
||||
&& (send_needly->opcode == ZEND_SEND_VAL
|
||||
|| send_needly->opcode == ZEND_SEND_VAR)
|
||||
) {
|
||||
bool ok = 1;
|
||||
|
||||
HashTable *src = Z_ARRVAL_P(CT_CONSTANT_EX(op_array, op->op2.constant));
|
||||
HashTable *src = Z_ARRVAL_P(CT_CONSTANT_EX(op_array, send_array->op1.constant));
|
||||
HashTable *dst;
|
||||
zval *val, tmp;
|
||||
zend_ulong idx;
|
||||
|
@ -459,15 +458,59 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa)
|
|||
}
|
||||
|
||||
if (ok) {
|
||||
uint32_t op_num = send_needly - op_array->opcodes;
|
||||
zend_ssa_op *ssa_op = ssa->ops + op_num;
|
||||
|
||||
if (ssa_op->op1_use >= 0) {
|
||||
/* Reconstruct SSA */
|
||||
int var_num = ssa_op->op1_use;
|
||||
zend_ssa_var *var = ssa->vars + var_num;
|
||||
|
||||
ZEND_ASSERT(ssa_op->op1_def < 0);
|
||||
zend_ssa_unlink_use_chain(ssa, op_num, ssa_op->op1_use);
|
||||
ssa_op->op1_use = -1;
|
||||
ssa_op->op1_use_chain = -1;
|
||||
op_num = call_info->caller_call_opline - op_array->opcodes;
|
||||
ssa_op = ssa->ops + op_num;
|
||||
ssa_op->op1_use = var_num;
|
||||
ssa_op->op1_use_chain = var->use_chain;
|
||||
var->use_chain = op_num;
|
||||
}
|
||||
|
||||
ZVAL_ARR(&tmp, dst);
|
||||
|
||||
/* Update opcode */
|
||||
op->opcode = ZEND_IN_ARRAY;
|
||||
op->extended_value = strict;
|
||||
op->op2.constant = zend_optimizer_add_literal(op_array, &tmp);
|
||||
if (has_opdata) {
|
||||
MAKE_NOP(op + 1);
|
||||
call_info->caller_call_opline->opcode = ZEND_IN_ARRAY;
|
||||
call_info->caller_call_opline->extended_value = strict;
|
||||
call_info->caller_call_opline->op1_type = send_needly->op1_type;
|
||||
call_info->caller_call_opline->op1.num = send_needly->op1.num;
|
||||
call_info->caller_call_opline->op2_type = IS_CONST;
|
||||
call_info->caller_call_opline->op2.constant = zend_optimizer_add_literal(op_array, &tmp);
|
||||
if (call_info->caller_init_opline->extended_value == 3) {
|
||||
MAKE_NOP(call_info->caller_call_opline - 1);
|
||||
}
|
||||
MAKE_NOP(call_info->caller_init_opline);
|
||||
MAKE_NOP(send_needly);
|
||||
MAKE_NOP(send_array);
|
||||
removed_ops++;
|
||||
|
||||
op_num = call_info->caller_call_opline - op_array->opcodes;
|
||||
ssa_op = ssa->ops + op_num;
|
||||
if (ssa_op->result_def >= 0) {
|
||||
int var = ssa_op->result_def;
|
||||
int use = ssa->vars[var].use_chain;
|
||||
|
||||
/* If the result is used only in a JMPZ/JMPNZ, replace result type with
|
||||
* IS_TMP_VAR, which will enable use of smart branches. Don't do this
|
||||
* in other cases, as not all opcodes support both VAR and TMP. */
|
||||
if (ssa->vars[var].phi_use_chain == NULL
|
||||
&& ssa->ops[use].op1_use == var
|
||||
&& ssa->ops[use].op1_use_chain == -1
|
||||
&& (op_array->opcodes[use].opcode == ZEND_JMPZ
|
||||
|| op_array->opcodes[use].opcode == ZEND_JMPNZ)) {
|
||||
call_info->caller_call_opline->result_type = IS_TMP_VAR;
|
||||
op_array->opcodes[use].op1_type = IS_TMP_VAR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -610,7 +653,6 @@ static void zend_ssa_replace_control_link(zend_op_array *op_array, zend_ssa *ssa
|
|||
case ZEND_ASSERT_CHECK:
|
||||
case ZEND_JMP_NULL:
|
||||
case ZEND_BIND_INIT_STATIC_OR_JMP:
|
||||
case ZEND_JMP_FRAMELESS:
|
||||
if (ZEND_OP2_JMP_ADDR(opline) == op_array->opcodes + old->start) {
|
||||
ZEND_SET_OP_JMP_ADDR(opline, opline->op2, op_array->opcodes + dst->start);
|
||||
}
|
||||
|
@ -965,7 +1007,7 @@ optimize_nop:
|
|||
static bool zend_dfa_try_to_replace_result(zend_op_array *op_array, zend_ssa *ssa, int def, int cv_var)
|
||||
{
|
||||
int result_var = ssa->ops[def].result_def;
|
||||
uint32_t cv = EX_NUM_TO_VAR(ssa->vars[cv_var].var);
|
||||
int cv = EX_NUM_TO_VAR(ssa->vars[cv_var].var);
|
||||
|
||||
if (result_var >= 0
|
||||
&& !(ssa->var_info[cv_var].type & MAY_BE_REF)
|
||||
|
|
|
@ -48,7 +48,6 @@ static void zend_delete_call_instructions(zend_op_array *op_array, zend_op *opli
|
|||
case ZEND_INIT_STATIC_METHOD_CALL:
|
||||
case ZEND_INIT_METHOD_CALL:
|
||||
case ZEND_INIT_FCALL:
|
||||
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:
|
||||
if (call == 0) {
|
||||
MAKE_NOP(opline);
|
||||
return;
|
||||
|
@ -78,10 +77,8 @@ static void zend_delete_call_instructions(zend_op_array *op_array, zend_op *opli
|
|||
|
||||
static void zend_try_inline_call(zend_op_array *op_array, zend_op *fcall, zend_op *opline, zend_function *func)
|
||||
{
|
||||
const uint32_t no_discard = RETURN_VALUE_USED(opline) ? 0 : ZEND_ACC_NODISCARD;
|
||||
|
||||
if (func->type == ZEND_USER_FUNCTION
|
||||
&& !(func->op_array.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_HAS_TYPE_HINTS|ZEND_ACC_DEPRECATED|no_discard))
|
||||
&& !(func->op_array.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_HAS_TYPE_HINTS))
|
||||
/* TODO: function copied from trait may be inconsistent ??? */
|
||||
&& !(func->op_array.fn_flags & (ZEND_ACC_TRAIT_CLONE))
|
||||
&& fcall->extended_value >= func->op_array.required_num_args
|
||||
|
@ -172,15 +169,12 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
|||
case ZEND_INIT_METHOD_CALL:
|
||||
case ZEND_INIT_FCALL:
|
||||
case ZEND_NEW:
|
||||
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:
|
||||
/* The argument passing optimizations are valid for prototypes as well,
|
||||
* as inheritance cannot change between ref <-> non-ref arguments. */
|
||||
call_stack[call].func = zend_optimizer_get_called_func(
|
||||
ctx->script, op_array, opline, &call_stack[call].is_prototype);
|
||||
call_stack[call].try_inline =
|
||||
!call_stack[call].is_prototype
|
||||
&& opline->opcode != ZEND_NEW
|
||||
&& opline->opcode != ZEND_INIT_PARENT_PROPERTY_HOOK_CALL;
|
||||
!call_stack[call].is_prototype && opline->opcode != ZEND_NEW;
|
||||
ZEND_FALLTHROUGH;
|
||||
case ZEND_INIT_DYNAMIC_CALL:
|
||||
case ZEND_INIT_USER_CALL:
|
||||
|
@ -204,31 +198,26 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
|||
fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func);
|
||||
literal_dtor(&ZEND_OP2_LITERAL(fcall));
|
||||
fcall->op2.constant = fcall->op2.constant + 1;
|
||||
if (opline->opcode != ZEND_CALLABLE_CONVERT) {
|
||||
opline->opcode = zend_get_call_op(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);
|
||||
literal_dtor(&op_array->literals[fcall->op2.constant]);
|
||||
literal_dtor(&op_array->literals[fcall->op2.constant + 2]);
|
||||
fcall->op2.constant = fcall->op2.constant + 1;
|
||||
if (opline->opcode != ZEND_CALLABLE_CONVERT) {
|
||||
opline->opcode = zend_get_call_op(fcall, call_stack[call].func);
|
||||
}
|
||||
} else if (fcall->opcode == ZEND_INIT_STATIC_METHOD_CALL
|
||||
|| fcall->opcode == ZEND_INIT_METHOD_CALL
|
||||
|| fcall->opcode == ZEND_INIT_PARENT_PROPERTY_HOOK_CALL
|
||||
|| fcall->opcode == ZEND_NEW) {
|
||||
/* We don't have specialized opcodes for this, do nothing */
|
||||
} else {
|
||||
ZEND_UNREACHABLE();
|
||||
}
|
||||
|
||||
/* If the INIT opcode changed the DO opcode can also change to
|
||||
* a more optimized one.
|
||||
*
|
||||
* At this point we also know whether or not the result of
|
||||
* the DO opcode is used, allowing to optimize calls to
|
||||
* ZEND_ACC_NODISCARD functions. */
|
||||
if (opline->opcode != ZEND_CALLABLE_CONVERT) {
|
||||
opline->opcode = zend_get_call_op(fcall, call_stack[call].func, !RESULT_UNUSED(opline));
|
||||
}
|
||||
|
||||
if ((ZEND_OPTIMIZER_PASS_16 & ctx->optimization_level)
|
||||
&& call_stack[call].try_inline
|
||||
&& opline->opcode != ZEND_CALLABLE_CONVERT) {
|
||||
|
|
|
@ -161,13 +161,17 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
|||
}
|
||||
break;
|
||||
|
||||
case ZEND_FETCH_CLASS_CONSTANT: {
|
||||
bool is_prototype;
|
||||
const zend_class_constant *cc = zend_fetch_class_const_info(ctx->script, op_array, opline, &is_prototype);
|
||||
if (!cc || is_prototype) {
|
||||
break;
|
||||
}
|
||||
const zval *c = &cc->value;
|
||||
case ZEND_FETCH_CLASS_CONSTANT:
|
||||
if (opline->op2_type == IS_CONST &&
|
||||
Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) {
|
||||
|
||||
zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1(
|
||||
ctx->script, op_array, opline);
|
||||
if (ce) {
|
||||
zend_class_constant *cc = zend_hash_find_ptr(
|
||||
&ce->constants_table, Z_STR(ZEND_OP2_LITERAL(opline)));
|
||||
if (cc && !(ZEND_CLASS_CONST_FLAGS(cc) & ZEND_ACC_DEPRECATED) && (ZEND_CLASS_CONST_FLAGS(cc) & ZEND_ACC_PPP_MASK) == ZEND_ACC_PUBLIC && !(ce->ce_flags & ZEND_ACC_TRAIT)) {
|
||||
zval *c = &cc->value;
|
||||
if (Z_TYPE_P(c) == IS_CONSTANT_AST) {
|
||||
zend_ast *ast = Z_ASTVAL_P(c);
|
||||
if (ast->kind != ZEND_AST_CONSTANT
|
||||
|
@ -178,9 +182,12 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
|||
} else {
|
||||
ZVAL_COPY_OR_DUP(&result, c);
|
||||
}
|
||||
|
||||
replace_by_const_or_qm_assign(op_array, opline, &result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ZEND_DO_ICALL: {
|
||||
zend_op *send1_opline = opline - 1;
|
||||
|
@ -315,7 +322,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
|||
case ZEND_JMPZ:
|
||||
case ZEND_JMPNZ:
|
||||
if (opline->op1_type == IS_CONST) {
|
||||
bool should_jmp = zend_is_true(&ZEND_OP1_LITERAL(opline));
|
||||
int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(opline));
|
||||
|
||||
if (opline->opcode == ZEND_JMPZ) {
|
||||
should_jmp = !should_jmp;
|
||||
|
@ -337,6 +344,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
|||
case ZEND_RETURN:
|
||||
case ZEND_RETURN_BY_REF:
|
||||
case ZEND_GENERATOR_RETURN:
|
||||
case ZEND_EXIT:
|
||||
case ZEND_THROW:
|
||||
case ZEND_MATCH_ERROR:
|
||||
case ZEND_CATCH:
|
||||
|
@ -353,7 +361,6 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
|||
case ZEND_JMP_NULL:
|
||||
case ZEND_VERIFY_NEVER_TYPE:
|
||||
case ZEND_BIND_INIT_STATIC_OR_JMP:
|
||||
case ZEND_JMP_FRAMELESS:
|
||||
collect_constants = 0;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -88,7 +88,8 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
|||
MAKE_NOP(opline);
|
||||
} else if ((target->opcode == ZEND_RETURN ||
|
||||
target->opcode == ZEND_RETURN_BY_REF ||
|
||||
target->opcode == ZEND_GENERATOR_RETURN) &&
|
||||
target->opcode == ZEND_GENERATOR_RETURN ||
|
||||
target->opcode == ZEND_EXIT) &&
|
||||
!(op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) {
|
||||
/* JMP L, L: RETURN to immediate RETURN */
|
||||
*opline = *target;
|
||||
|
|
|
@ -789,10 +789,14 @@ static bool can_ct_eval_func_call(zend_function *func, zend_string *name, uint32
|
|||
/* The functions chosen here are simple to implement and either likely to affect a branch,
|
||||
* or just happened to be commonly used with constant operands in WP (need to test other
|
||||
* applications as well, of course). */
|
||||
static inline zend_result ct_eval_func_call_ex(
|
||||
zend_op_array *op_array, zval *result, zend_function *func, uint32_t num_args, zval **args) {
|
||||
static inline zend_result ct_eval_func_call(
|
||||
zend_op_array *op_array, zval *result, zend_string *name, uint32_t num_args, zval **args) {
|
||||
uint32_t i;
|
||||
zend_string *name = func->common.function_name;
|
||||
zend_function *func = zend_hash_find_ptr(CG(function_table), name);
|
||||
if (!func || func->type != ZEND_INTERNAL_FUNCTION) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (num_args == 1 && Z_TYPE_P(args[0]) == IS_STRING &&
|
||||
zend_optimizer_eval_special_func_call(result, name, Z_STR_P(args[0])) == SUCCESS) {
|
||||
return SUCCESS;
|
||||
|
@ -851,15 +855,6 @@ static inline zend_result ct_eval_func_call_ex(
|
|||
return retval;
|
||||
}
|
||||
|
||||
static inline zend_result ct_eval_func_call(
|
||||
zend_op_array *op_array, zval *result, zend_string *name, uint32_t num_args, zval **args) {
|
||||
zend_function *func = zend_hash_find_ptr(CG(function_table), name);
|
||||
if (!func || func->type != ZEND_INTERNAL_FUNCTION) {
|
||||
return FAILURE;
|
||||
}
|
||||
return ct_eval_func_call_ex(op_array, result, func, num_args, args);
|
||||
}
|
||||
|
||||
#define SET_RESULT(op, zv) do { \
|
||||
if (ssa_op->op##_def >= 0) { \
|
||||
set_value(scdf, ctx, ssa_op->op##_def, zv); \
|
||||
|
@ -1713,51 +1708,6 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
|
|||
SET_RESULT_BOT(result);
|
||||
break;
|
||||
}
|
||||
case ZEND_FRAMELESS_ICALL_0:
|
||||
case ZEND_FRAMELESS_ICALL_1:
|
||||
case ZEND_FRAMELESS_ICALL_2:
|
||||
case ZEND_FRAMELESS_ICALL_3: {
|
||||
/* We already know it can't be evaluated, don't bother checking again */
|
||||
if (ssa_op->result_def < 0 || IS_BOT(&ctx->values[ssa_op->result_def])) {
|
||||
break;
|
||||
}
|
||||
|
||||
zval *args[3] = {NULL};
|
||||
zend_function *func = ZEND_FLF_FUNC(opline);
|
||||
uint32_t num_args = ZEND_FLF_NUM_ARGS(opline->opcode);
|
||||
|
||||
switch (num_args) {
|
||||
case 3: {
|
||||
zend_op *op_data = opline + 1;
|
||||
args[2] = get_op1_value(ctx, op_data, &ctx->scdf.ssa->ops[op_data - ctx->scdf.op_array->opcodes]);
|
||||
ZEND_FALLTHROUGH;
|
||||
}
|
||||
case 2:
|
||||
args[1] = get_op2_value(ctx, opline, &ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes]);
|
||||
ZEND_FALLTHROUGH;
|
||||
case 1:
|
||||
args[0] = get_op1_value(ctx, opline, &ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes]);
|
||||
break;
|
||||
}
|
||||
for (uint32_t i = 0; i < num_args; i++) {
|
||||
if (!args[i]) {
|
||||
SET_RESULT_BOT(result);
|
||||
return;
|
||||
} else if (IS_BOT(args[i]) || IS_PARTIAL_ARRAY(args[i])) {
|
||||
SET_RESULT_BOT(result);
|
||||
return;
|
||||
} else if (IS_TOP(args[i])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ct_eval_func_call_ex(scdf->op_array, &zv, func, num_args, args) == SUCCESS) {
|
||||
SET_RESULT(result, &zv);
|
||||
zval_ptr_dtor_nogc(&zv);
|
||||
break;
|
||||
}
|
||||
SET_RESULT_BOT(result);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/* If we have no explicit implementation return BOT */
|
||||
|
@ -2205,13 +2155,7 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var,
|
|||
if (opline->opcode == ZEND_DO_ICALL) {
|
||||
removed_ops = remove_call(ctx, opline, ssa_op) - 1;
|
||||
} else {
|
||||
bool has_op_data = opline->opcode == ZEND_FRAMELESS_ICALL_3;
|
||||
zend_ssa_remove_instr(ssa, opline, ssa_op);
|
||||
removed_ops++;
|
||||
if (has_op_data) {
|
||||
zend_ssa_remove_instr(ssa, opline + 1, ssa_op + 1);
|
||||
removed_ops++;
|
||||
}
|
||||
}
|
||||
ssa_op->result_def = var_num;
|
||||
opline->opcode = ZEND_QM_ASSIGN;
|
||||
|
@ -2247,13 +2191,8 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var,
|
|||
if (opline->opcode == ZEND_DO_ICALL) {
|
||||
removed_ops = remove_call(ctx, opline, ssa_op);
|
||||
} else {
|
||||
bool has_op_data = opline->opcode == ZEND_FRAMELESS_ICALL_3;
|
||||
zend_ssa_remove_instr(ssa, opline, ssa_op);
|
||||
removed_ops++;
|
||||
if (has_op_data) {
|
||||
zend_ssa_remove_instr(ssa, opline + 1, ssa_op + 1);
|
||||
removed_ops++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ssa_op->op1_def == var_num) {
|
||||
|
|
|
@ -61,7 +61,6 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32
|
|||
case ZEND_INIT_FCALL:
|
||||
case ZEND_INIT_METHOD_CALL:
|
||||
case ZEND_INIT_STATIC_METHOD_CALL:
|
||||
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:
|
||||
call_stack[call] = call_info;
|
||||
func = zend_optimizer_get_called_func(
|
||||
script, op_array, opline, &is_prototype);
|
||||
|
@ -74,13 +73,11 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32
|
|||
call_info->num_args = opline->extended_value;
|
||||
call_info->next_callee = func_info->callee_info;
|
||||
call_info->is_prototype = is_prototype;
|
||||
call_info->is_frameless = false;
|
||||
func_info->callee_info = call_info;
|
||||
|
||||
if (build_flags & ZEND_CALL_TREE) {
|
||||
call_info->next_caller = NULL;
|
||||
} else if (func->type == ZEND_INTERNAL_FUNCTION
|
||||
|| func->op_array.filename != script->filename) {
|
||||
} else if (func->type == ZEND_INTERNAL_FUNCTION) {
|
||||
call_info->next_caller = NULL;
|
||||
} else {
|
||||
zend_func_info *callee_func_info = ZEND_FUNC_INFO(&func->op_array);
|
||||
|
@ -105,24 +102,6 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32
|
|||
call_info = NULL;
|
||||
call++;
|
||||
break;
|
||||
case ZEND_FRAMELESS_ICALL_0:
|
||||
case ZEND_FRAMELESS_ICALL_1:
|
||||
case ZEND_FRAMELESS_ICALL_2:
|
||||
case ZEND_FRAMELESS_ICALL_3: {
|
||||
func = ZEND_FLF_FUNC(opline);
|
||||
zend_call_info *call_info = zend_arena_calloc(arena, 1, sizeof(zend_call_info));
|
||||
call_info->caller_op_array = op_array;
|
||||
call_info->caller_init_opline = opline;
|
||||
call_info->caller_call_opline = NULL;
|
||||
call_info->callee_func = func;
|
||||
call_info->num_args = ZEND_FLF_NUM_ARGS(opline->opcode);
|
||||
call_info->next_callee = func_info->callee_info;
|
||||
call_info->is_prototype = false;
|
||||
call_info->is_frameless = true;
|
||||
call_info->next_caller = NULL;
|
||||
func_info->callee_info = call_info;
|
||||
break;
|
||||
}
|
||||
case ZEND_DO_FCALL:
|
||||
case ZEND_DO_ICALL:
|
||||
case ZEND_DO_UCALL:
|
||||
|
@ -163,6 +142,10 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32
|
|||
call_info->send_unpack = 1;
|
||||
}
|
||||
break;
|
||||
case ZEND_EXIT:
|
||||
/* In this case the DO_CALL opcode may have been dropped
|
||||
* and caller_call_opline will be NULL. */
|
||||
break;
|
||||
}
|
||||
opline++;
|
||||
}
|
||||
|
@ -277,14 +260,12 @@ ZEND_API zend_call_info **zend_build_call_map(zend_arena **arena, zend_func_info
|
|||
if (call->caller_call_opline) {
|
||||
map[call->caller_call_opline - op_array->opcodes] = call;
|
||||
}
|
||||
if (!call->is_frameless) {
|
||||
for (i = 0; i < call->num_args; i++) {
|
||||
if (call->arg_info[i].opline) {
|
||||
map[call->arg_info[i].opline - op_array->opcodes] = call;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
/* }}} */
|
||||
|
|
|
@ -38,7 +38,6 @@ struct _zend_call_info {
|
|||
bool send_unpack; /* Parameters passed by SEND_UNPACK or SEND_ARRAY */
|
||||
bool named_args; /* Function has named arguments */
|
||||
bool is_prototype; /* An overridden child method may be called */
|
||||
bool is_frameless; /* A frameless function sends arguments through operands */
|
||||
int num_args; /* Number of arguments, excluding named and variadic arguments */
|
||||
zend_send_arg_info arg_info[1];
|
||||
};
|
||||
|
|
|
@ -28,20 +28,13 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc
|
|||
{
|
||||
zend_basic_block *blocks = cfg->blocks;
|
||||
|
||||
zend_worklist work;
|
||||
ALLOCA_FLAG(list_use_heap)
|
||||
ZEND_WORKLIST_ALLOCA(&work, cfg->blocks_count, list_use_heap);
|
||||
|
||||
zend_worklist_push(&work, b - cfg->blocks);
|
||||
|
||||
while (zend_worklist_len(&work)) {
|
||||
while (1) {
|
||||
int i;
|
||||
b = cfg->blocks + zend_worklist_pop(&work);
|
||||
|
||||
b->flags |= ZEND_BB_REACHABLE;
|
||||
if (b->successors_count == 0) {
|
||||
b->flags |= ZEND_BB_EXIT;
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < b->successors_count; i++) {
|
||||
|
@ -93,14 +86,22 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc
|
|||
succ->flags |= ZEND_BB_FOLLOW;
|
||||
}
|
||||
|
||||
/* Check reachability of successor */
|
||||
if (!(succ->flags & ZEND_BB_REACHABLE)) {
|
||||
zend_worklist_push(&work, succ - cfg->blocks);
|
||||
}
|
||||
}
|
||||
if (i == b->successors_count - 1) {
|
||||
/* Tail call optimization */
|
||||
if (succ->flags & ZEND_BB_REACHABLE) {
|
||||
return;
|
||||
}
|
||||
|
||||
ZEND_WORKLIST_FREE_ALLOCA(&work, list_use_heap);
|
||||
b = succ;
|
||||
break;
|
||||
} else {
|
||||
/* Recursively check reachability */
|
||||
if (!(succ->flags & ZEND_BB_REACHABLE)) {
|
||||
zend_mark_reachable(opcodes, cfg, succ);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -306,6 +307,7 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array,
|
|||
}
|
||||
break;
|
||||
case ZEND_MATCH_ERROR:
|
||||
case ZEND_EXIT:
|
||||
case ZEND_THROW:
|
||||
/* Don't treat THROW as terminator if it's used in expression context,
|
||||
* as we may lose live ranges when eliminating unreachable code. */
|
||||
|
@ -372,7 +374,6 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array,
|
|||
case ZEND_ASSERT_CHECK:
|
||||
case ZEND_JMP_NULL:
|
||||
case ZEND_BIND_INIT_STATIC_OR_JMP:
|
||||
case ZEND_JMP_FRAMELESS:
|
||||
BB_START(OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes);
|
||||
BB_START(i + 1);
|
||||
break;
|
||||
|
@ -509,6 +510,7 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array,
|
|||
case ZEND_RETURN:
|
||||
case ZEND_RETURN_BY_REF:
|
||||
case ZEND_GENERATOR_RETURN:
|
||||
case ZEND_EXIT:
|
||||
case ZEND_THROW:
|
||||
case ZEND_MATCH_ERROR:
|
||||
case ZEND_VERIFY_NEVER_TYPE:
|
||||
|
@ -526,7 +528,6 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array,
|
|||
case ZEND_ASSERT_CHECK:
|
||||
case ZEND_JMP_NULL:
|
||||
case ZEND_BIND_INIT_STATIC_OR_JMP:
|
||||
case ZEND_JMP_FRAMELESS:
|
||||
block->successors_count = 2;
|
||||
block->successors[0] = block_map[OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes];
|
||||
block->successors[1] = j + 1;
|
||||
|
|
|
@ -122,7 +122,6 @@ add_op1_def:
|
|||
}
|
||||
break;
|
||||
case ZEND_ASSIGN_STATIC_PROP_OP:
|
||||
case ZEND_FRAMELESS_ICALL_3:
|
||||
next = opline + 1;
|
||||
if (next->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
|
||||
var_num = EX_VAR_TO_NUM(next->op1.var);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "zend_func_info.h"
|
||||
#include "zend_call_graph.h"
|
||||
#include "zend_dump.h"
|
||||
#include "zend_smart_str.h"
|
||||
#include "ext/standard/php_string.h"
|
||||
|
||||
void zend_dump_ht(HashTable *ht)
|
||||
{
|
||||
|
@ -66,27 +66,13 @@ void zend_dump_const(const zval *zv)
|
|||
case IS_DOUBLE:
|
||||
fprintf(stderr, " float(%g)", Z_DVAL_P(zv));
|
||||
break;
|
||||
case IS_STRING: {
|
||||
smart_str escaped_string = {0};
|
||||
smart_str_append_escaped(&escaped_string, Z_STRVAL_P(zv), Z_STRLEN_P(zv));
|
||||
smart_str_0(&escaped_string);
|
||||
case IS_STRING:;
|
||||
zend_string *escaped_string = php_addcslashes(Z_STR_P(zv), "\"\\", 2);
|
||||
|
||||
fprintf(stderr, " string(\"");
|
||||
fprintf(stderr, " string(\"%s\")", ZSTR_VAL(escaped_string));
|
||||
|
||||
/* Also escape '"' */
|
||||
for (size_t i = 0; i < ZSTR_LEN(escaped_string.s); i++) {
|
||||
if (ZSTR_VAL(escaped_string.s)[i] == '"') {
|
||||
fprintf(stderr, "\\\"");
|
||||
} else {
|
||||
putc(ZSTR_VAL(escaped_string.s)[i], stderr);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "\")");
|
||||
|
||||
smart_str_free_ex(&escaped_string, false);
|
||||
zend_string_release(escaped_string);
|
||||
break;
|
||||
}
|
||||
case IS_ARRAY:
|
||||
fprintf(stderr, " array(...)");
|
||||
break;
|
||||
|
@ -151,7 +137,7 @@ static void zend_dump_unused_op(const zend_op *opline, znode_op op, uint32_t fla
|
|||
}
|
||||
}
|
||||
|
||||
ZEND_API void zend_dump_var(const zend_op_array *op_array, uint8_t var_type, uint32_t var_num)
|
||||
ZEND_API void zend_dump_var(const zend_op_array *op_array, uint8_t var_type, int var_num)
|
||||
{
|
||||
if (var_type == IS_CV && var_num < op_array->last_var) {
|
||||
fprintf(stderr, "CV%d($%s)", var_num, op_array->vars[var_num]->val);
|
||||
|
@ -380,7 +366,7 @@ static void zend_dump_ssa_var_info(const zend_ssa *ssa, int ssa_var_num, uint32_
|
|||
dump_flags);
|
||||
}
|
||||
|
||||
ZEND_API void zend_dump_ssa_var(const zend_op_array *op_array, const zend_ssa *ssa, int ssa_var_num, uint8_t var_type, uint32_t var_num, uint32_t dump_flags)
|
||||
ZEND_API void zend_dump_ssa_var(const zend_op_array *op_array, const zend_ssa *ssa, int ssa_var_num, uint8_t var_type, int var_num, uint32_t dump_flags)
|
||||
{
|
||||
if (ssa_var_num >= 0) {
|
||||
fprintf(stderr, "#%d.", ssa_var_num);
|
||||
|
@ -477,11 +463,6 @@ ZEND_API void zend_dump_op(const zend_op_array *op_array, const zend_basic_block
|
|||
fprintf(stderr, "OP_%d", (int)opline->opcode);
|
||||
}
|
||||
|
||||
if (ZEND_OP_IS_FRAMELESS_ICALL(opline->opcode)) {
|
||||
zend_function *func = ZEND_FLF_FUNC(opline);
|
||||
fprintf(stderr, "(%s)", ZSTR_VAL(func->common.function_name));
|
||||
}
|
||||
|
||||
if (ZEND_VM_EXT_NUM == (flags & ZEND_VM_EXT_MASK)) {
|
||||
fprintf(stderr, " %u", opline->extended_value);
|
||||
} else if (ZEND_VM_EXT_OP == (flags & ZEND_VM_EXT_MASK)) {
|
||||
|
@ -943,6 +924,7 @@ void zend_dump_op_array_name(const zend_op_array *op_array)
|
|||
|
||||
ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, const char *msg, const void *data)
|
||||
{
|
||||
int i;
|
||||
const zend_cfg *cfg = NULL;
|
||||
const zend_ssa *ssa = NULL;
|
||||
zend_func_info *func_info = NULL;
|
||||
|
@ -1028,7 +1010,7 @@ ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_fl
|
|||
}
|
||||
|
||||
if (ssa && ssa->var_info) {
|
||||
for (uint32_t i = 0; i < op_array->last_var; i++) {
|
||||
for (i = 0; i < op_array->last_var; i++) {
|
||||
fprintf(stderr, " ; ");
|
||||
zend_dump_ssa_var(op_array, ssa, i, IS_CV, i, dump_flags);
|
||||
fprintf(stderr, "\n");
|
||||
|
@ -1056,7 +1038,7 @@ ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_fl
|
|||
}
|
||||
if (op_array->last_live_range && (dump_flags & ZEND_DUMP_LIVE_RANGES)) {
|
||||
fprintf(stderr, "LIVE RANGES:\n");
|
||||
for (int i = 0; i < op_array->last_live_range; i++) {
|
||||
for (i = 0; i < op_array->last_live_range; i++) {
|
||||
fprintf(stderr,
|
||||
" %u: %04u - %04u ",
|
||||
EX_VAR_TO_NUM(op_array->live_range[i].var & ~ZEND_LIVE_MASK),
|
||||
|
@ -1083,7 +1065,7 @@ ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_fl
|
|||
}
|
||||
if (op_array->last_try_catch) {
|
||||
fprintf(stderr, "EXCEPTION TABLE:\n");
|
||||
for (int i = 0; i < op_array->last_try_catch; i++) {
|
||||
for (i = 0; i < op_array->last_try_catch; i++) {
|
||||
fprintf(stderr, " BB%u",
|
||||
cfg->map[op_array->try_catch_array[i].try_op]);
|
||||
if (op_array->try_catch_array[i].catch_op) {
|
||||
|
@ -1116,7 +1098,7 @@ ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_fl
|
|||
}
|
||||
if (op_array->last_live_range && (dump_flags & ZEND_DUMP_LIVE_RANGES)) {
|
||||
fprintf(stderr, "LIVE RANGES:\n");
|
||||
for (int i = 0; i < op_array->last_live_range; i++) {
|
||||
for (i = 0; i < op_array->last_live_range; i++) {
|
||||
fprintf(stderr,
|
||||
" %u: %04u - %04u ",
|
||||
EX_VAR_TO_NUM(op_array->live_range[i].var & ~ZEND_LIVE_MASK),
|
||||
|
@ -1143,7 +1125,7 @@ ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_fl
|
|||
}
|
||||
if (op_array->last_try_catch) {
|
||||
fprintf(stderr, "EXCEPTION TABLE:\n");
|
||||
for (int i = 0; i < op_array->last_try_catch; i++) {
|
||||
for (i = 0; i < op_array->last_try_catch; i++) {
|
||||
fprintf(stderr,
|
||||
" %04u",
|
||||
op_array->try_catch_array[i].try_op);
|
||||
|
@ -1189,6 +1171,20 @@ void zend_dump_dominators(const zend_op_array *op_array, const zend_cfg *cfg)
|
|||
}
|
||||
}
|
||||
|
||||
void zend_dump_variables(const zend_op_array *op_array)
|
||||
{
|
||||
int j;
|
||||
|
||||
fprintf(stderr, "\nCV Variables for \"");
|
||||
zend_dump_op_array_name(op_array);
|
||||
fprintf(stderr, "\"\n");
|
||||
for (j = 0; j < op_array->last_var; j++) {
|
||||
fprintf(stderr, " ");
|
||||
zend_dump_var(op_array, IS_CV, j);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
void zend_dump_ssa_variables(const zend_op_array *op_array, const zend_ssa *ssa, uint32_t dump_flags)
|
||||
{
|
||||
int j;
|
||||
|
|
|
@ -39,9 +39,10 @@ ZEND_API void zend_dump_op_line(const zend_op_array *op_array, const zend_basic_
|
|||
void zend_dump_dominators(const zend_op_array *op_array, const zend_cfg *cfg);
|
||||
void zend_dump_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const zend_dfg *dfg);
|
||||
void zend_dump_phi_placement(const zend_op_array *op_array, const zend_ssa *ssa);
|
||||
void zend_dump_variables(const zend_op_array *op_array);
|
||||
void zend_dump_ssa_variables(const zend_op_array *op_array, const zend_ssa *ssa, uint32_t dump_flags);
|
||||
ZEND_API void zend_dump_ssa_var(const zend_op_array *op_array, const zend_ssa *ssa, int ssa_var_num, uint8_t var_type, uint32_t var_num, uint32_t dump_flags);
|
||||
ZEND_API void zend_dump_var(const zend_op_array *op_array, uint8_t var_type, uint32_t var_num);
|
||||
ZEND_API void zend_dump_ssa_var(const zend_op_array *op_array, const zend_ssa *ssa, int ssa_var_num, uint8_t var_type, int var_num, uint32_t dump_flags);
|
||||
ZEND_API void zend_dump_var(const zend_op_array *op_array, uint8_t var_type, int var_num);
|
||||
void zend_dump_op_array_name(const zend_op_array *op_array);
|
||||
void zend_dump_const(const zval *zv);
|
||||
void zend_dump_ht(HashTable *ht);
|
||||
|
|
|
@ -51,23 +51,21 @@ typedef struct _func_info_t {
|
|||
|
||||
static uint32_t zend_range_info(const zend_call_info *call_info, const zend_ssa *ssa)
|
||||
{
|
||||
ZEND_ASSERT(!call_info->is_frameless);
|
||||
|
||||
if (!call_info->send_unpack
|
||||
&& (call_info->num_args == 2 || call_info->num_args == 3)
|
||||
&& ssa
|
||||
&& !(ssa->cfg.flags & ZEND_SSA_TSSA)) {
|
||||
zend_op_array *op_array = call_info->caller_op_array;
|
||||
uint32_t t1 = _ssa_op1_info(op_array, ssa, call_info->arg_info[0].opline,
|
||||
ssa->ops ? &ssa->ops[call_info->arg_info[0].opline - op_array->opcodes] : NULL);
|
||||
&ssa->ops[call_info->arg_info[0].opline - op_array->opcodes]);
|
||||
uint32_t t2 = _ssa_op1_info(op_array, ssa, call_info->arg_info[1].opline,
|
||||
ssa->ops ? &ssa->ops[call_info->arg_info[1].opline - op_array->opcodes] : NULL);
|
||||
&ssa->ops[call_info->arg_info[1].opline - op_array->opcodes]);
|
||||
uint32_t t3 = 0;
|
||||
uint32_t tmp = MAY_BE_RC1 | MAY_BE_ARRAY;
|
||||
|
||||
if (call_info->num_args == 3) {
|
||||
t3 = _ssa_op1_info(op_array, ssa, call_info->arg_info[2].opline,
|
||||
ssa->ops ? &ssa->ops[call_info->arg_info[2].opline - op_array->opcodes] : NULL);
|
||||
&ssa->ops[call_info->arg_info[2].opline - op_array->opcodes]);
|
||||
}
|
||||
if ((t1 & MAY_BE_STRING) && (t2 & MAY_BE_STRING)) {
|
||||
tmp |= MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_DOUBLE | MAY_BE_ARRAY_OF_STRING;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* This is a generated file, edit the .stub.php files instead. */
|
||||
|
||||
static const func_info_t func_infos[] = {
|
||||
F1("clone", MAY_BE_OBJECT),
|
||||
F1("zend_version", MAY_BE_STRING),
|
||||
FN("func_get_args", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_ANY),
|
||||
F1("get_class_vars", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF),
|
||||
|
@ -25,13 +24,9 @@ static const func_info_t func_infos[] = {
|
|||
F1("bcmul", MAY_BE_STRING),
|
||||
F1("bcdiv", MAY_BE_STRING),
|
||||
F1("bcmod", MAY_BE_STRING),
|
||||
F1("bcdivmod", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
|
||||
F1("bcpowmod", MAY_BE_STRING),
|
||||
F1("bcpow", MAY_BE_STRING),
|
||||
F1("bcsqrt", MAY_BE_STRING),
|
||||
F1("bcfloor", MAY_BE_STRING),
|
||||
F1("bcceil", MAY_BE_STRING),
|
||||
F1("bcround", MAY_BE_STRING),
|
||||
FN("bzopen", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
F1("bzerror", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING),
|
||||
F1("cal_from_jd", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_NULL),
|
||||
|
@ -47,7 +42,6 @@ static const func_info_t func_infos[] = {
|
|||
F1("curl_multi_strerror", MAY_BE_STRING|MAY_BE_NULL),
|
||||
F1("curl_share_init", MAY_BE_OBJECT),
|
||||
F1("curl_share_strerror", MAY_BE_STRING|MAY_BE_NULL),
|
||||
F1("curl_share_init_persistent", MAY_BE_OBJECT),
|
||||
F1("curl_strerror", MAY_BE_STRING|MAY_BE_NULL),
|
||||
F1("curl_version", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_FALSE),
|
||||
F1("date", MAY_BE_STRING),
|
||||
|
@ -80,6 +74,8 @@ static const func_info_t func_infos[] = {
|
|||
F1("date_sunrise", MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_FALSE),
|
||||
F1("date_sunset", MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_FALSE),
|
||||
F1("date_sun_info", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_FALSE|MAY_BE_ARRAY_OF_TRUE|MAY_BE_ARRAY_OF_LONG),
|
||||
FN("dba_popen", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
FN("dba_open", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
FN("dba_key_split", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
|
||||
F1("dba_handlers", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING),
|
||||
FN("dba_list", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
|
||||
|
@ -105,6 +101,8 @@ static const func_info_t func_infos[] = {
|
|||
F1("imagecreatetruecolor", MAY_BE_OBJECT|MAY_BE_FALSE),
|
||||
#if defined(PHP_WIN32)
|
||||
F1("imagegrabwindow", MAY_BE_OBJECT|MAY_BE_FALSE),
|
||||
#endif
|
||||
#if defined(PHP_WIN32)
|
||||
F1("imagegrabscreen", MAY_BE_OBJECT|MAY_BE_FALSE),
|
||||
#endif
|
||||
F1("imagerotate", MAY_BE_OBJECT|MAY_BE_FALSE),
|
||||
|
@ -131,11 +129,15 @@ static const func_info_t func_infos[] = {
|
|||
F1("imagecreatefromgd", MAY_BE_OBJECT|MAY_BE_FALSE),
|
||||
F1("imagecreatefromgd2", MAY_BE_OBJECT|MAY_BE_FALSE),
|
||||
F1("imagecreatefromgd2part", MAY_BE_OBJECT|MAY_BE_FALSE),
|
||||
#if defined(HAVE_GD_BMP)
|
||||
F1("imagecreatefrombmp", MAY_BE_OBJECT|MAY_BE_FALSE),
|
||||
#endif
|
||||
F1("imagecolorsforindex", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG),
|
||||
F1("imagegetclip", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_LONG),
|
||||
#if defined(HAVE_GD_FREETYPE)
|
||||
F1("imageftbbox", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_LONG|MAY_BE_FALSE),
|
||||
#endif
|
||||
#if defined(HAVE_GD_FREETYPE)
|
||||
F1("imagefttext", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_LONG|MAY_BE_FALSE),
|
||||
#endif
|
||||
F1("imagecrop", MAY_BE_OBJECT|MAY_BE_FALSE),
|
||||
|
@ -179,7 +181,11 @@ static const func_info_t func_infos[] = {
|
|||
F1("hash_hkdf", MAY_BE_STRING),
|
||||
#if defined(PHP_MHASH_BC)
|
||||
F1("mhash_get_hash_name", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
#endif
|
||||
#if defined(PHP_MHASH_BC)
|
||||
F1("mhash_keygen_s2k", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
#endif
|
||||
#if defined(PHP_MHASH_BC)
|
||||
F1("mhash", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
#endif
|
||||
F1("iconv_substr", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
|
@ -232,13 +238,29 @@ static const func_info_t func_infos[] = {
|
|||
F1("mb_get_info", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_STRING|MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_NULL),
|
||||
#if defined(HAVE_MBREGEX)
|
||||
F1("mb_regex_encoding", MAY_BE_STRING|MAY_BE_BOOL),
|
||||
#endif
|
||||
#if defined(HAVE_MBREGEX)
|
||||
F1("mb_ereg_replace", MAY_BE_STRING|MAY_BE_FALSE|MAY_BE_NULL),
|
||||
#endif
|
||||
#if defined(HAVE_MBREGEX)
|
||||
F1("mb_eregi_replace", MAY_BE_STRING|MAY_BE_FALSE|MAY_BE_NULL),
|
||||
#endif
|
||||
#if defined(HAVE_MBREGEX)
|
||||
F1("mb_ereg_replace_callback", MAY_BE_STRING|MAY_BE_FALSE|MAY_BE_NULL),
|
||||
#endif
|
||||
#if defined(HAVE_MBREGEX)
|
||||
F1("mb_split", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
|
||||
#endif
|
||||
#if defined(HAVE_MBREGEX)
|
||||
F1("mb_ereg_search_pos", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_LONG|MAY_BE_FALSE),
|
||||
#endif
|
||||
#if defined(HAVE_MBREGEX)
|
||||
F1("mb_ereg_search_regs", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_FALSE|MAY_BE_FALSE),
|
||||
#endif
|
||||
#if defined(HAVE_MBREGEX)
|
||||
F1("mb_ereg_search_getregs", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_FALSE|MAY_BE_FALSE),
|
||||
#endif
|
||||
#if defined(HAVE_MBREGEX)
|
||||
F1("mb_regex_set_options", MAY_BE_STRING),
|
||||
#endif
|
||||
F1("mysqli_affected_rows", MAY_BE_LONG|MAY_BE_STRING),
|
||||
|
@ -286,6 +308,39 @@ static const func_info_t func_infos[] = {
|
|||
F1("mysqli_stat", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
F1("mysqli_store_result", MAY_BE_OBJECT|MAY_BE_FALSE),
|
||||
F1("mysqli_use_result", MAY_BE_OBJECT|MAY_BE_FALSE),
|
||||
FN("oci_new_connect", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
FN("oci_connect", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
FN("oci_pconnect", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
F1("oci_error", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
|
||||
FN("oci_parse", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
FN("oci_get_implicit_resultset", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
FN("oci_password_change", MAY_BE_RESOURCE|MAY_BE_BOOL),
|
||||
FN("oci_new_cursor", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
FN("odbc_prepare", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
FN("odbc_exec", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
FN("odbc_connect", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
FN("odbc_pconnect", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
FN("odbc_tables", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
FN("odbc_columns", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
FN("odbc_gettypeinfo", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
FN("odbc_primarykeys", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35)
|
||||
FN("odbc_procedurecolumns", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
#endif
|
||||
#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35)
|
||||
FN("odbc_procedures", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
#endif
|
||||
#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35)
|
||||
FN("odbc_foreignkeys", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
#endif
|
||||
FN("odbc_specialcolumns", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
FN("odbc_statistics", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
#if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) &&!defined(HAVE_SOLID_35)
|
||||
FN("odbc_tableprivileges", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
#endif
|
||||
#if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) &&!defined(HAVE_SOLID_35)
|
||||
FN("odbc_columnprivileges", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
#endif
|
||||
F1("opcache_get_status", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_FALSE),
|
||||
F1("opcache_get_configuration", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_FALSE),
|
||||
F1("openssl_x509_parse", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_FALSE),
|
||||
|
@ -310,7 +365,6 @@ static const func_info_t func_infos[] = {
|
|||
F1("pg_tty", MAY_BE_STRING),
|
||||
F1("pg_host", MAY_BE_STRING),
|
||||
F1("pg_version", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_NULL),
|
||||
F1("pg_jit", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_NULL),
|
||||
F1("pg_parameter_status", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
F1("pg_query", MAY_BE_OBJECT|MAY_BE_FALSE),
|
||||
F1("pg_query_params", MAY_BE_OBJECT|MAY_BE_FALSE),
|
||||
|
@ -360,6 +414,7 @@ static const func_info_t func_infos[] = {
|
|||
#if defined(HAVE_GETRLIMIT)
|
||||
F1("posix_getrlimit", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
|
||||
#endif
|
||||
F1("pspell_suggest", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
|
||||
F1("random_bytes", MAY_BE_STRING),
|
||||
#if defined(HAVE_HISTORY_LIST)
|
||||
F1("readline_list_history", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
|
||||
|
@ -379,6 +434,8 @@ static const func_info_t func_infos[] = {
|
|||
FN("sodium_crypto_kx_server_session_keys", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
|
||||
#if defined(crypto_secretstream_xchacha20poly1305_ABYTES)
|
||||
FN("sodium_crypto_secretstream_xchacha20poly1305_init_push", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
|
||||
#endif
|
||||
#if defined(crypto_secretstream_xchacha20poly1305_ABYTES)
|
||||
FN("sodium_crypto_secretstream_xchacha20poly1305_pull", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
|
||||
#endif
|
||||
F1("class_implements", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
|
||||
|
@ -413,7 +470,7 @@ static const func_info_t func_infos[] = {
|
|||
FN("array_rand", MAY_BE_LONG|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING),
|
||||
F1("base64_encode", MAY_BE_STRING),
|
||||
F1("base64_decode", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
F1("long2ip", MAY_BE_STRING),
|
||||
F1("long2ip", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
F1("getenv", MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
|
||||
F1("getopt", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_FALSE|MAY_BE_FALSE),
|
||||
#if defined(HAVE_NANOSLEEP)
|
||||
|
@ -421,13 +478,14 @@ static const func_info_t func_infos[] = {
|
|||
#endif
|
||||
F1("get_current_user", MAY_BE_STRING),
|
||||
FN("get_cfg_var", MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_FALSE),
|
||||
F1("error_get_last", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_NULL),
|
||||
F1("error_get_last", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_NULL),
|
||||
F1("highlight_file", MAY_BE_STRING|MAY_BE_BOOL),
|
||||
F1("php_strip_whitespace", MAY_BE_STRING),
|
||||
F1("highlight_string", MAY_BE_STRING|MAY_BE_TRUE),
|
||||
F1("highlight_string", MAY_BE_STRING|MAY_BE_BOOL),
|
||||
F1("ini_get_all", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_NULL|MAY_BE_FALSE),
|
||||
F1("set_include_path", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
F1("print_r", MAY_BE_STRING|MAY_BE_TRUE),
|
||||
F1("get_include_path", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
F1("print_r", MAY_BE_STRING|MAY_BE_BOOL),
|
||||
#if defined(HAVE_GETSERVBYPORT)
|
||||
F1("getservbyport", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
#endif
|
||||
|
@ -460,8 +518,12 @@ static const func_info_t func_infos[] = {
|
|||
F1("md5_file", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
F1("sha1", MAY_BE_STRING),
|
||||
F1("sha1_file", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
#if defined(HAVE_INET_NTOP)
|
||||
F1("inet_ntop", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
#endif
|
||||
#if defined(HAVE_INET_PTON)
|
||||
F1("inet_pton", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
#endif
|
||||
F1("metaphone", MAY_BE_STRING),
|
||||
F1("headers_list", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
|
||||
F1("htmlspecialchars", MAY_BE_STRING),
|
||||
|
@ -510,7 +572,9 @@ static const func_info_t func_infos[] = {
|
|||
F1("getcwd", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
F1("readdir", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
F1("scandir", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
|
||||
#if defined(HAVE_GLOB)
|
||||
F1("glob", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
|
||||
#endif
|
||||
F1("exec", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
F1("system", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
F1("escapeshellcmd", MAY_BE_STRING),
|
||||
|
@ -539,7 +603,6 @@ static const func_info_t func_infos[] = {
|
|||
F1("fsockopen", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
FN("pfsockopen", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
F1("http_build_query", MAY_BE_STRING),
|
||||
F1("request_parse_body", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_ARRAY),
|
||||
F1("image_type_to_mime_type", MAY_BE_STRING),
|
||||
F1("image_type_to_extension", MAY_BE_STRING|MAY_BE_FALSE),
|
||||
F1("getimagesize", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
|
||||
|
@ -561,6 +624,8 @@ static const func_info_t func_infos[] = {
|
|||
F1("number_format", MAY_BE_STRING),
|
||||
#if defined(HAVE_GETTIMEOFDAY)
|
||||
F1("microtime", MAY_BE_STRING|MAY_BE_DOUBLE),
|
||||
#endif
|
||||
#if defined(HAVE_GETTIMEOFDAY)
|
||||
F1("gettimeofday", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_DOUBLE),
|
||||
#endif
|
||||
#if defined(HAVE_GETRUSAGE)
|
||||
|
@ -572,6 +637,8 @@ static const func_info_t func_infos[] = {
|
|||
F1("password_hash", MAY_BE_STRING),
|
||||
#if defined(PHP_CAN_SUPPORT_PROC_OPEN)
|
||||
F1("proc_open", MAY_BE_RESOURCE|MAY_BE_FALSE),
|
||||
#endif
|
||||
#if defined(PHP_CAN_SUPPORT_PROC_OPEN)
|
||||
F1("proc_get_status", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_FALSE|MAY_BE_ARRAY_OF_TRUE|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING),
|
||||
#endif
|
||||
F1("quoted_printable_decode", MAY_BE_STRING),
|
||||
|
|
|
@ -543,7 +543,7 @@ ZEND_API void zend_ssa_find_false_dependencies(const zend_op_array *op_array, ze
|
|||
/* }}} */
|
||||
|
||||
/* From "Hacker's Delight" */
|
||||
static zend_ulong minOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
|
||||
zend_ulong minOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
|
||||
{
|
||||
zend_ulong m, temp;
|
||||
|
||||
|
@ -567,7 +567,7 @@ static zend_ulong minOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
|
|||
return a | c;
|
||||
}
|
||||
|
||||
static zend_ulong maxOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
|
||||
zend_ulong maxOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
|
||||
{
|
||||
zend_ulong m, temp;
|
||||
|
||||
|
@ -590,7 +590,7 @@ static zend_ulong maxOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
|
|||
return b | d;
|
||||
}
|
||||
|
||||
static zend_ulong minAND(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
|
||||
zend_ulong minAND(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
|
||||
{
|
||||
zend_ulong m, temp;
|
||||
|
||||
|
@ -613,7 +613,7 @@ static zend_ulong minAND(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
|
|||
return a & c;
|
||||
}
|
||||
|
||||
static zend_ulong maxAND(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
|
||||
zend_ulong maxAND(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
|
||||
{
|
||||
zend_ulong m, temp;
|
||||
|
||||
|
@ -637,6 +637,16 @@ static zend_ulong maxAND(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
|
|||
return b & d;
|
||||
}
|
||||
|
||||
zend_ulong minXOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
|
||||
{
|
||||
return minAND(a, b, ~d, ~c) | minAND(~b, ~a, c, d);
|
||||
}
|
||||
|
||||
zend_ulong maxXOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
|
||||
{
|
||||
return maxOR(0, maxAND(a, b, ~d, ~c), 0, maxAND(~b, ~a, c, d));
|
||||
}
|
||||
|
||||
/* Based on "Hacker's Delight" */
|
||||
|
||||
/*
|
||||
|
@ -1968,10 +1978,6 @@ static uint32_t get_ssa_alias_types(zend_ssa_alias_kind alias) {
|
|||
/* TODO: support for array keys and ($str . "")*/ \
|
||||
__type |= MAY_BE_RCN; \
|
||||
} \
|
||||
if ((__type & MAY_BE_RC1) && (__type & MAY_BE_OBJECT)) {\
|
||||
/* TODO: object may be captured by magic handlers */\
|
||||
__type |= MAY_BE_RCN; \
|
||||
} \
|
||||
if (__ssa_var->alias) { \
|
||||
__type |= get_ssa_alias_types(__ssa_var->alias); \
|
||||
} \
|
||||
|
@ -1997,15 +2003,10 @@ static uint32_t get_ssa_alias_types(zend_ssa_alias_kind alias) {
|
|||
#define UPDATE_SSA_OBJ_TYPE(_ce, _is_instanceof, var) \
|
||||
do { \
|
||||
if (var >= 0) { \
|
||||
zend_class_entry *__ce = (_ce); \
|
||||
bool __is_instanceof = (_is_instanceof); \
|
||||
if (__ce && (__ce->ce_flags & ZEND_ACC_FINAL)) { \
|
||||
__is_instanceof = false; \
|
||||
} \
|
||||
if (ssa_var_info[var].ce != __ce || \
|
||||
ssa_var_info[var].is_instanceof != __is_instanceof) { \
|
||||
ssa_var_info[var].ce = __ce; \
|
||||
ssa_var_info[var].is_instanceof = __is_instanceof; \
|
||||
if (ssa_var_info[var].ce != (_ce) || \
|
||||
ssa_var_info[var].is_instanceof != (_is_instanceof)) { \
|
||||
ssa_var_info[var].ce = (_ce); \
|
||||
ssa_var_info[var].is_instanceof = (_is_instanceof); \
|
||||
if (update_worklist) { \
|
||||
add_usages(op_array, ssa, worklist, var); \
|
||||
} \
|
||||
|
@ -2409,7 +2410,7 @@ static const zend_property_info *lookup_prop_info(const zend_class_entry *ce, ze
|
|||
/* If the class is linked, reuse the precise runtime logic. */
|
||||
if ((ce->ce_flags & ZEND_ACC_LINKED)
|
||||
&& (!scope || (scope->ce_flags & ZEND_ACC_LINKED))) {
|
||||
const zend_class_entry *prev_scope = EG(fake_scope);
|
||||
zend_class_entry *prev_scope = EG(fake_scope);
|
||||
EG(fake_scope) = scope;
|
||||
prop_info = zend_get_property_info(ce, name, 1);
|
||||
EG(fake_scope) = prev_scope;
|
||||
|
@ -3023,14 +3024,7 @@ static zend_always_inline zend_result _zend_update_type_info(
|
|||
break;
|
||||
case ZEND_ASSIGN_OBJ:
|
||||
if (opline->op1_type == IS_CV) {
|
||||
zend_class_entry *ce = ssa_var_info[ssa_op->op1_use].ce;
|
||||
bool add_rc = (t1 & (MAY_BE_OBJECT|MAY_BE_REF)) && (!ce
|
||||
|| ce->__set
|
||||
/* Non-default write_property may be set within create_object. */
|
||||
|| ce->create_object
|
||||
|| ce->default_object_handlers->write_property != zend_std_write_property
|
||||
|| ssa_var_info[ssa_op->op1_use].is_instanceof);
|
||||
tmp = (t1 & (MAY_BE_REF|MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN))|(add_rc ? (MAY_BE_RC1|MAY_BE_RCN) : 0);
|
||||
tmp = (t1 & (MAY_BE_REF|MAY_BE_OBJECT))|MAY_BE_RC1|MAY_BE_RCN;
|
||||
UPDATE_SSA_TYPE(tmp, ssa_op->op1_def);
|
||||
COPY_SSA_OBJ_TYPE(ssa_op->op1_use, ssa_op->op1_def);
|
||||
}
|
||||
|
@ -3163,7 +3157,7 @@ static zend_always_inline zend_result _zend_update_type_info(
|
|||
}
|
||||
break;
|
||||
case ZEND_ASSIGN_OBJ_REF:
|
||||
if (opline->op1_type == IS_CV && ssa_op->op1_def >= 0) {
|
||||
if (opline->op1_type == IS_CV) {
|
||||
tmp = t1;
|
||||
if (tmp & MAY_BE_OBJECT) {
|
||||
tmp |= MAY_BE_RC1 | MAY_BE_RCN;
|
||||
|
@ -3354,12 +3348,6 @@ static zend_always_inline zend_result _zend_update_type_info(
|
|||
}
|
||||
break;
|
||||
case ZEND_FETCH_CLASS_STATIC:
|
||||
if (op_array->scope && (op_array->scope->ce_flags & ZEND_ACC_FINAL)) {
|
||||
UPDATE_SSA_OBJ_TYPE(op_array->scope, 0, ssa_op->result_def);
|
||||
} else {
|
||||
UPDATE_SSA_OBJ_TYPE(NULL, 0, ssa_op->result_def);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
UPDATE_SSA_OBJ_TYPE(NULL, 0, ssa_op->result_def);
|
||||
break;
|
||||
|
@ -3383,19 +3371,9 @@ static zend_always_inline zend_result _zend_update_type_info(
|
|||
UPDATE_SSA_OBJ_TYPE(ce, 0, ssa_op->result_def);
|
||||
} else if ((t1 & MAY_BE_CLASS) && ssa_op->op1_use >= 0 && ssa_var_info[ssa_op->op1_use].ce) {
|
||||
UPDATE_SSA_OBJ_TYPE(ssa_var_info[ssa_op->op1_use].ce, ssa_var_info[ssa_op->op1_use].is_instanceof, ssa_op->result_def);
|
||||
if (!ssa_var_info[ssa_op->result_def].is_instanceof) {
|
||||
ce = ssa_var_info[ssa_op->op1_use].ce;
|
||||
}
|
||||
} else {
|
||||
UPDATE_SSA_OBJ_TYPE(NULL, 0, ssa_op->result_def);
|
||||
}
|
||||
/* New objects without constructors cannot escape. */
|
||||
if (ce
|
||||
&& !ce->constructor
|
||||
&& !ce->create_object
|
||||
&& ce->default_object_handlers->get_constructor == zend_std_get_constructor) {
|
||||
tmp &= ~MAY_BE_RCN;
|
||||
}
|
||||
UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
|
||||
break;
|
||||
case ZEND_CLONE:
|
||||
|
@ -3843,38 +3821,6 @@ static zend_always_inline zend_result _zend_update_type_info(
|
|||
UPDATE_SSA_OBJ_TYPE(ce, 1, ssa_op->result_def);
|
||||
}
|
||||
break;
|
||||
case ZEND_FRAMELESS_ICALL_1:
|
||||
case ZEND_FRAMELESS_ICALL_2:
|
||||
case ZEND_FRAMELESS_ICALL_3:
|
||||
if (ssa_op->op1_def >= 0) {
|
||||
ZEND_ASSERT(ssa_op->op1_use >= 0);
|
||||
tmp = ssa->var_info[ssa_op->op1_use].type;
|
||||
if (tmp & MAY_BE_RC1) {
|
||||
tmp |= MAY_BE_RCN;
|
||||
}
|
||||
UPDATE_SSA_TYPE(tmp, ssa_op->op1_def);
|
||||
}
|
||||
if (ssa_op->op2_def >= 0) {
|
||||
ZEND_ASSERT(ssa_op->op2_use >= 0);
|
||||
tmp = ssa->var_info[ssa_op->op2_use].type;
|
||||
if (tmp & MAY_BE_RC1) {
|
||||
tmp |= MAY_BE_RCN;
|
||||
}
|
||||
UPDATE_SSA_TYPE(tmp, ssa_op->op2_def);
|
||||
}
|
||||
if (opline->opcode == ZEND_FRAMELESS_ICALL_3) {
|
||||
zend_ssa_op *next_ssa_op = ssa_op + 1;
|
||||
if (next_ssa_op->op1_def >= 0) {
|
||||
ZEND_ASSERT(next_ssa_op->op1_use >= 0);
|
||||
tmp = ssa->var_info[next_ssa_op->op1_use].type;
|
||||
if (tmp & MAY_BE_RC1) {
|
||||
tmp |= MAY_BE_RCN;
|
||||
}
|
||||
UPDATE_SSA_TYPE(tmp, next_ssa_op->op1_def);
|
||||
}
|
||||
}
|
||||
ZEND_FALLTHROUGH;
|
||||
case ZEND_FRAMELESS_ICALL_0:
|
||||
case ZEND_DO_FCALL:
|
||||
case ZEND_DO_ICALL:
|
||||
case ZEND_DO_UCALL:
|
||||
|
@ -3905,21 +3851,9 @@ static zend_always_inline zend_result _zend_update_type_info(
|
|||
UPDATE_SSA_OBJ_TYPE(zend_ce_closure, /* is_instanceof */ false, ssa_op->result_def);
|
||||
break;
|
||||
case ZEND_FETCH_CONSTANT:
|
||||
case ZEND_FETCH_CLASS_CONSTANT:
|
||||
UPDATE_SSA_TYPE(MAY_BE_RC1|MAY_BE_RCN|MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY, ssa_op->result_def);
|
||||
break;
|
||||
case ZEND_FETCH_CLASS_CONSTANT: {
|
||||
bool is_prototype;
|
||||
const zend_class_constant *cc = zend_fetch_class_const_info(script, op_array, opline, &is_prototype);
|
||||
if (!cc || !ZEND_TYPE_IS_SET(cc->type)) {
|
||||
UPDATE_SSA_TYPE(MAY_BE_RC1|MAY_BE_RCN|MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY, ssa_op->result_def);
|
||||
break;
|
||||
}
|
||||
UPDATE_SSA_TYPE(zend_convert_type(script, cc->type, &ce), ssa_op->result_def);
|
||||
if (ce) {
|
||||
UPDATE_SSA_OBJ_TYPE(ce, /* is_instanceof */ true, ssa_op->result_def);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ZEND_STRLEN:
|
||||
case ZEND_COUNT:
|
||||
case ZEND_FUNC_NUM_ARGS:
|
||||
|
@ -4001,73 +3935,12 @@ static zend_always_inline zend_result _zend_update_type_info(
|
|||
/* Forbidden opcodes */
|
||||
ZEND_UNREACHABLE();
|
||||
break;
|
||||
case ZEND_FETCH_CLASS_NAME:
|
||||
UPDATE_SSA_TYPE(MAY_BE_STRING|MAY_BE_RCN, ssa_op->result_def);
|
||||
break;
|
||||
case ZEND_ISSET_ISEMPTY_THIS:
|
||||
UPDATE_SSA_TYPE(MAY_BE_BOOL, ssa_op->result_def);
|
||||
break;
|
||||
case ZEND_DECLARE_LAMBDA_FUNCTION:
|
||||
UPDATE_SSA_TYPE(MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN, ssa_op->result_def);
|
||||
UPDATE_SSA_OBJ_TYPE(zend_ce_closure, /* is_instanceof */ false, ssa_op->result_def);
|
||||
break;
|
||||
case ZEND_PRE_DEC_STATIC_PROP:
|
||||
case ZEND_PRE_INC_STATIC_PROP:
|
||||
case ZEND_POST_DEC_STATIC_PROP:
|
||||
case ZEND_POST_INC_STATIC_PROP: {
|
||||
if (ssa_op->result_def >= 0) {
|
||||
const zend_property_info *prop_info = zend_fetch_static_prop_info(script, op_array, ssa, opline);
|
||||
zend_class_entry *prop_ce;
|
||||
tmp = zend_fetch_prop_type(script, prop_info, &prop_ce);
|
||||
/* Internal objects may result in essentially anything. */
|
||||
if (tmp & MAY_BE_OBJECT) {
|
||||
goto unknown_opcode;
|
||||
}
|
||||
tmp &= MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING|MAY_BE_BOOL|MAY_BE_NULL;
|
||||
if (tmp & MAY_BE_STRING) {
|
||||
tmp |= MAY_BE_RC1 | MAY_BE_RCN;
|
||||
}
|
||||
UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ZEND_SPACESHIP:
|
||||
UPDATE_SSA_TYPE(MAY_BE_LONG, ssa_op->result_def);
|
||||
break;
|
||||
case ZEND_FETCH_GLOBALS:
|
||||
UPDATE_SSA_TYPE(MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF|MAY_BE_RC1|MAY_BE_RCN, ssa_op->result_def);
|
||||
break;
|
||||
default:
|
||||
#ifdef ZEND_DEBUG_TYPE_INFERENCE
|
||||
if (ssa_op->result_def >= 0) {
|
||||
switch (opline->opcode) {
|
||||
case ZEND_FETCH_R:
|
||||
case ZEND_FETCH_W:
|
||||
case ZEND_FETCH_RW:
|
||||
case ZEND_FETCH_IS:
|
||||
case ZEND_FETCH_UNSET:
|
||||
case ZEND_YIELD_FROM:
|
||||
/* Currently unimplemented due to some assumptions in JIT. See:
|
||||
* https://github.com/php/php-src/pull/13304#issuecomment-1926668141 */
|
||||
case ZEND_SEPARATE:
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Missing result type inference for opcode %s, line %d\n", zend_get_opcode_name(opline->opcode), opline->lineno);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ssa_op->op1_def >= 0) {
|
||||
fprintf(stderr, "Missing op1 type inference for opcode %s, line %d\n", zend_get_opcode_name(opline->opcode), opline->lineno);
|
||||
}
|
||||
if (ssa_op->op2_def >= 0) {
|
||||
fprintf(stderr, "Missing op2 type inference for opcode %s, line %d\n", zend_get_opcode_name(opline->opcode), opline->lineno);
|
||||
}
|
||||
#endif
|
||||
unknown_opcode:
|
||||
if (ssa_op->op1_def >= 0) {
|
||||
tmp = MAY_BE_ANY | MAY_BE_REF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
|
||||
UPDATE_SSA_TYPE(tmp, ssa_op->op1_def);
|
||||
}
|
||||
unknown_opcode:
|
||||
if (ssa_op->result_def >= 0) {
|
||||
tmp = MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
|
||||
if (opline->result_type == IS_TMP_VAR) {
|
||||
|
@ -5005,6 +4878,8 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op
|
|||
|
||||
switch (opline->opcode) {
|
||||
case ZEND_NOP:
|
||||
case ZEND_IS_IDENTICAL:
|
||||
case ZEND_IS_NOT_IDENTICAL:
|
||||
case ZEND_QM_ASSIGN:
|
||||
case ZEND_JMP:
|
||||
case ZEND_CHECK_VAR:
|
||||
|
@ -5026,14 +4901,9 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op
|
|||
case ZEND_FUNC_NUM_ARGS:
|
||||
case ZEND_FUNC_GET_ARGS:
|
||||
case ZEND_COPY_TMP:
|
||||
case ZEND_JMP_NULL:
|
||||
case ZEND_JMP_FRAMELESS:
|
||||
return 0;
|
||||
case ZEND_IS_IDENTICAL:
|
||||
case ZEND_IS_NOT_IDENTICAL:
|
||||
case ZEND_CASE_STRICT:
|
||||
/* Array to array comparison may lead to recursion. */
|
||||
return (t1 & t2) & MAY_BE_ARRAY_OF_ARRAY;
|
||||
case ZEND_JMP_NULL:
|
||||
return 0;
|
||||
case ZEND_SEND_VAR:
|
||||
case ZEND_SEND_VAL:
|
||||
case ZEND_SEND_REF:
|
||||
|
@ -5184,7 +5054,7 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op
|
|||
return 0;
|
||||
case ZEND_ASSIGN_DIM:
|
||||
if ((opline+1)->op1_type == IS_CV) {
|
||||
if (OP1_DATA_INFO() & MAY_BE_UNDEF) {
|
||||
if (_ssa_op1_info(op_array, ssa, opline+1, ssa_op+1) & MAY_BE_UNDEF) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -5198,7 +5068,7 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op
|
|||
return 1;
|
||||
}
|
||||
if ((opline+1)->op1_type == IS_CV) {
|
||||
if (OP1_DATA_INFO() & MAY_BE_UNDEF) {
|
||||
if (_ssa_op1_info(op_array, ssa, opline+1, ssa_op+1) & MAY_BE_UNDEF) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -197,13 +197,13 @@ DEFINE_SSA_OP_DEF_INFO(result)
|
|||
|
||||
#define OP1_INFO() (_ssa_op1_info(op_array, ssa, opline, ssa_op))
|
||||
#define OP2_INFO() (_ssa_op2_info(op_array, ssa, opline, ssa_op))
|
||||
#define OP1_DATA_INFO() (_ssa_op1_info(op_array, ssa, (opline+1), ssa_op ? (ssa_op+1) : NULL))
|
||||
#define OP2_DATA_INFO() (_ssa_op2_info(op_array, ssa, (opline+1), ssa_op ? (ssa_op+1) : NULL))
|
||||
#define OP1_DATA_INFO() (_ssa_op1_info(op_array, ssa, (opline+1), (ssa_op+1)))
|
||||
#define OP2_DATA_INFO() (_ssa_op2_info(op_array, ssa, (opline+1), (ssa_op+1)))
|
||||
#define RES_USE_INFO() (_ssa_result_info(op_array, ssa, opline, ssa_op))
|
||||
#define OP1_DEF_INFO() (_ssa_op1_def_info(op_array, ssa, opline, ssa_op))
|
||||
#define OP2_DEF_INFO() (_ssa_op2_def_info(op_array, ssa, opline, ssa_op))
|
||||
#define OP1_DATA_DEF_INFO() (_ssa_op1_def_info(op_array, ssa, (opline+1), ssa_op ? (ssa_op+1) : NULL))
|
||||
#define OP2_DATA_DEF_INFO() (_ssa_op2_def_info(op_array, ssa, (opline+1), ssa_op ? (ssa_op+1) : NULL))
|
||||
#define OP1_DATA_DEF_INFO() (_ssa_op1_def_info(op_array, ssa, (opline+1), (ssa_op+1)))
|
||||
#define OP2_DATA_DEF_INFO() (_ssa_op2_def_info(op_array, ssa, (opline+1), (ssa_op+1)))
|
||||
#define RES_INFO() (_ssa_result_def_info(op_array, ssa, opline, ssa_op))
|
||||
|
||||
static zend_always_inline bool zend_add_will_overflow(zend_long a, zend_long b) {
|
||||
|
|
|
@ -82,7 +82,30 @@ zend_result zend_optimizer_eval_unary_op(zval *result, uint8_t opcode, zval *op1
|
|||
|
||||
zend_result zend_optimizer_eval_cast(zval *result, uint32_t type, zval *op1) /* {{{ */
|
||||
{
|
||||
if (zend_try_ct_eval_cast(result, type, op1)) {
|
||||
switch (type) {
|
||||
case IS_NULL:
|
||||
ZVAL_NULL(result);
|
||||
return SUCCESS;
|
||||
case _IS_BOOL:
|
||||
ZVAL_BOOL(result, zval_is_true(op1));
|
||||
return SUCCESS;
|
||||
case IS_LONG:
|
||||
ZVAL_LONG(result, zval_get_long(op1));
|
||||
return SUCCESS;
|
||||
case IS_DOUBLE:
|
||||
ZVAL_DOUBLE(result, zval_get_double(op1));
|
||||
return SUCCESS;
|
||||
case IS_STRING:
|
||||
/* Conversion from double to string takes into account run-time
|
||||
'precision' setting and cannot be evaluated at compile-time */
|
||||
if (Z_TYPE_P(op1) != IS_ARRAY && Z_TYPE_P(op1) != IS_DOUBLE) {
|
||||
ZVAL_STR(result, zval_get_string(op1));
|
||||
return SUCCESS;
|
||||
}
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
ZVAL_COPY(result, op1);
|
||||
convert_to_array(result);
|
||||
return SUCCESS;
|
||||
}
|
||||
return FAILURE;
|
||||
|
@ -699,7 +722,6 @@ void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, z
|
|||
case ZEND_ASSERT_CHECK:
|
||||
case ZEND_JMP_NULL:
|
||||
case ZEND_BIND_INIT_STATIC_OR_JMP:
|
||||
case ZEND_JMP_FRAMELESS:
|
||||
ZEND_SET_OP_JMP_ADDR(new_opline, new_opline->op2, ZEND_OP2_JMP_ADDR(opline));
|
||||
break;
|
||||
case ZEND_FE_FETCH_R:
|
||||
|
@ -744,7 +766,6 @@ void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_
|
|||
case ZEND_ASSERT_CHECK:
|
||||
case ZEND_JMP_NULL:
|
||||
case ZEND_BIND_INIT_STATIC_OR_JMP:
|
||||
case ZEND_JMP_FRAMELESS:
|
||||
ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP2_JMP_ADDR(opline) - shiftlist[ZEND_OP2_JMP_ADDR(opline) - op_array->opcodes]);
|
||||
break;
|
||||
case ZEND_CATCH:
|
||||
|
@ -771,42 +792,6 @@ void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_
|
|||
}
|
||||
}
|
||||
|
||||
static bool zend_optimizer_ignore_class(zval *ce_zv, zend_string *filename)
|
||||
{
|
||||
zend_class_entry *ce = Z_PTR_P(ce_zv);
|
||||
|
||||
if (ce->ce_flags & ZEND_ACC_PRELOADED) {
|
||||
Bucket *ce_bucket = (Bucket*)((uintptr_t)ce_zv - XtOffsetOf(Bucket, val));
|
||||
size_t offset = ce_bucket - EG(class_table)->arData;
|
||||
if (offset < EG(persistent_classes_count)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return ce->type == ZEND_USER_CLASS
|
||||
&& (!ce->info.user.filename || ce->info.user.filename != filename);
|
||||
}
|
||||
|
||||
static bool zend_optimizer_ignore_function(zval *fbc_zv, zend_string *filename)
|
||||
{
|
||||
zend_function *fbc = Z_PTR_P(fbc_zv);
|
||||
|
||||
if (fbc->type == ZEND_INTERNAL_FUNCTION) {
|
||||
return false;
|
||||
} else if (fbc->type == ZEND_USER_FUNCTION) {
|
||||
if (fbc->op_array.fn_flags & ZEND_ACC_PRELOADED) {
|
||||
Bucket *fbc_bucket = (Bucket*)((uintptr_t)fbc_zv - XtOffsetOf(Bucket, val));
|
||||
size_t offset = fbc_bucket - EG(function_table)->arData;
|
||||
if (offset < EG(persistent_functions_count)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return !fbc->op_array.filename || fbc->op_array.filename != filename;
|
||||
} else {
|
||||
ZEND_ASSERT(fbc->type == ZEND_EVAL_CODE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
zend_class_entry *zend_optimizer_get_class_entry(
|
||||
const zend_script *script, const zend_op_array *op_array, zend_string *lcname) {
|
||||
zend_class_entry *ce = script ? zend_hash_find_ptr(&script->class_table, lcname) : NULL;
|
||||
|
@ -814,9 +799,11 @@ zend_class_entry *zend_optimizer_get_class_entry(
|
|||
return ce;
|
||||
}
|
||||
|
||||
zval *ce_zv = zend_hash_find(CG(class_table), lcname);
|
||||
if (ce_zv && !zend_optimizer_ignore_class(ce_zv, op_array ? op_array->filename : NULL)) {
|
||||
return Z_PTR_P(ce_zv);
|
||||
ce = zend_hash_find_ptr(CG(class_table), lcname);
|
||||
if (ce
|
||||
&& (ce->type == ZEND_INTERNAL_CLASS
|
||||
|| (op_array && ce->info.user.filename == op_array->filename))) {
|
||||
return ce;
|
||||
}
|
||||
|
||||
if (op_array && op_array->scope && zend_string_equals_ci(op_array->scope->name, lcname)) {
|
||||
|
@ -835,66 +822,12 @@ zend_class_entry *zend_optimizer_get_class_entry_from_op1(
|
|||
}
|
||||
} else if (opline->op1_type == IS_UNUSED && op_array->scope
|
||||
&& !(op_array->scope->ce_flags & ZEND_ACC_TRAIT)
|
||||
&& ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF
|
||||
|| ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_STATIC
|
||||
&& (op_array->scope->ce_flags & ZEND_ACC_FINAL)))) {
|
||||
&& (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) {
|
||||
return op_array->scope;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const zend_class_constant *zend_fetch_class_const_info(
|
||||
const zend_script *script, const zend_op_array *op_array, const zend_op *opline, bool *is_prototype) {
|
||||
const zend_class_entry *ce = NULL;
|
||||
bool is_static_reference = false;
|
||||
|
||||
if (!opline || !op_array || opline->op2_type != IS_CONST || Z_TYPE_P(CRT_CONSTANT(opline->op2)) != IS_STRING) {
|
||||
return NULL;
|
||||
}
|
||||
if (opline->op1_type == IS_CONST) {
|
||||
zval *op1 = CRT_CONSTANT(opline->op1);
|
||||
if (Z_TYPE_P(op1) == IS_STRING) {
|
||||
if (script) {
|
||||
ce = zend_optimizer_get_class_entry(script, op_array, Z_STR_P(op1 + 1));
|
||||
} else {
|
||||
zval *ce_zv = zend_hash_find(EG(class_table), Z_STR_P(op1 + 1));
|
||||
if (ce_zv && !zend_optimizer_ignore_class(ce_zv, op_array->filename)) {
|
||||
ce = Z_PTR_P(ce_zv);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (opline->op1_type == IS_UNUSED
|
||||
&& op_array->scope && !(op_array->scope->ce_flags & ZEND_ACC_TRAIT)
|
||||
&& !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) {
|
||||
int fetch_type = opline->op1.num & ZEND_FETCH_CLASS_MASK;
|
||||
if (fetch_type == ZEND_FETCH_CLASS_SELF) {
|
||||
ce = op_array->scope;
|
||||
} else if (fetch_type == ZEND_FETCH_CLASS_STATIC) {
|
||||
ce = op_array->scope;
|
||||
is_static_reference = true;
|
||||
} else if (fetch_type == ZEND_FETCH_CLASS_PARENT) {
|
||||
if (op_array->scope->ce_flags & ZEND_ACC_LINKED) {
|
||||
ce = op_array->scope->parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ce || (ce->ce_flags & ZEND_ACC_TRAIT)) {
|
||||
return NULL;
|
||||
}
|
||||
zend_class_constant *const_info = zend_hash_find_ptr(&ce->constants_table, Z_STR_P(CRT_CONSTANT(opline->op2)));
|
||||
if (!const_info) {
|
||||
return NULL;
|
||||
}
|
||||
if ((ZEND_CLASS_CONST_FLAGS(const_info) & ZEND_ACC_DEPRECATED)
|
||||
|| ((ZEND_CLASS_CONST_FLAGS(const_info) & ZEND_ACC_PPP_MASK) != ZEND_ACC_PUBLIC && const_info->ce != op_array->scope)) {
|
||||
return NULL;
|
||||
}
|
||||
*is_prototype = is_static_reference
|
||||
&& !(const_info->ce->ce_flags & ZEND_ACC_FINAL) && !(ZEND_CLASS_CONST_FLAGS(const_info) & ZEND_ACC_FINAL);
|
||||
|
||||
return const_info;
|
||||
}
|
||||
|
||||
zend_function *zend_optimizer_get_called_func(
|
||||
zend_script *script, zend_op_array *op_array, zend_op *opline, bool *is_prototype)
|
||||
{
|
||||
|
@ -904,12 +837,15 @@ zend_function *zend_optimizer_get_called_func(
|
|||
{
|
||||
zend_string *function_name = Z_STR_P(CRT_CONSTANT(opline->op2));
|
||||
zend_function *func;
|
||||
zval *func_zv;
|
||||
if (script && (func = zend_hash_find_ptr(&script->function_table, function_name)) != NULL) {
|
||||
return func;
|
||||
} else if ((func_zv = zend_hash_find(EG(function_table), function_name)) != NULL) {
|
||||
if (!zend_optimizer_ignore_function(func_zv, op_array->filename)) {
|
||||
return Z_PTR_P(func_zv);
|
||||
} else if ((func = zend_hash_find_ptr(EG(function_table), function_name)) != NULL) {
|
||||
if (func->type == ZEND_INTERNAL_FUNCTION) {
|
||||
return func;
|
||||
} else if (func->type == ZEND_USER_FUNCTION &&
|
||||
func->op_array.filename &&
|
||||
func->op_array.filename == op_array->filename) {
|
||||
return func;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -919,12 +855,15 @@ zend_function *zend_optimizer_get_called_func(
|
|||
if (opline->op2_type == IS_CONST && Z_TYPE_P(CRT_CONSTANT(opline->op2)) == IS_STRING) {
|
||||
zval *function_name = CRT_CONSTANT(opline->op2) + 1;
|
||||
zend_function *func;
|
||||
zval *func_zv;
|
||||
if (script && (func = zend_hash_find_ptr(&script->function_table, Z_STR_P(function_name)))) {
|
||||
return func;
|
||||
} else if ((func_zv = zend_hash_find(EG(function_table), Z_STR_P(function_name))) != NULL) {
|
||||
if (!zend_optimizer_ignore_function(func_zv, op_array->filename)) {
|
||||
return Z_PTR_P(func_zv);
|
||||
} else if ((func = zend_hash_find_ptr(EG(function_table), Z_STR_P(function_name))) != NULL) {
|
||||
if (func->type == ZEND_INTERNAL_FUNCTION) {
|
||||
return func;
|
||||
} else if (func->type == ZEND_USER_FUNCTION &&
|
||||
func->op_array.filename &&
|
||||
func->op_array.filename == op_array->filename) {
|
||||
return func;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -974,28 +913,6 @@ zend_function *zend_optimizer_get_called_func(
|
|||
}
|
||||
}
|
||||
break;
|
||||
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL: {
|
||||
zend_class_entry *scope = op_array->scope;
|
||||
ZEND_ASSERT(scope != NULL);
|
||||
if ((scope->ce_flags & ZEND_ACC_LINKED) && scope->parent) {
|
||||
zend_class_entry *parent_scope = scope->parent;
|
||||
zend_string *prop_name = Z_STR_P(CRT_CONSTANT(opline->op1));
|
||||
zend_property_hook_kind hook_kind = opline->op2.num;
|
||||
zend_property_info *prop_info = zend_get_property_info(parent_scope, prop_name, /* silent */ true);
|
||||
|
||||
if (prop_info
|
||||
&& prop_info != ZEND_WRONG_PROPERTY_INFO
|
||||
&& !(prop_info->flags & ZEND_ACC_PRIVATE)
|
||||
&& prop_info->hooks) {
|
||||
zend_function *fbc = prop_info->hooks[hook_kind];
|
||||
if (fbc) {
|
||||
*is_prototype = false;
|
||||
return fbc;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ZEND_NEW:
|
||||
{
|
||||
zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1(
|
||||
|
@ -1242,7 +1159,6 @@ static void zend_redo_pass_two(zend_op_array *op_array)
|
|||
case ZEND_ASSERT_CHECK:
|
||||
case ZEND_JMP_NULL:
|
||||
case ZEND_BIND_INIT_STATIC_OR_JMP:
|
||||
case ZEND_JMP_FRAMELESS:
|
||||
opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes];
|
||||
break;
|
||||
case ZEND_CATCH:
|
||||
|
@ -1364,7 +1280,6 @@ static void zend_redo_pass_two_ex(zend_op_array *op_array, zend_ssa *ssa)
|
|||
case ZEND_ASSERT_CHECK:
|
||||
case ZEND_JMP_NULL:
|
||||
case ZEND_BIND_INIT_STATIC_OR_JMP:
|
||||
case ZEND_JMP_FRAMELESS:
|
||||
opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes];
|
||||
break;
|
||||
case ZEND_CATCH:
|
||||
|
@ -1414,26 +1329,6 @@ static void zend_redo_pass_two_ex(zend_op_array *op_array, zend_ssa *ssa)
|
|||
}
|
||||
break;
|
||||
}
|
||||
#ifdef ZEND_VERIFY_TYPE_INFERENCE
|
||||
if (ssa_op->op1_use >= 0) {
|
||||
opline->op1_use_type = ssa->var_info[ssa_op->op1_use].type;
|
||||
}
|
||||
if (ssa_op->op2_use >= 0) {
|
||||
opline->op2_use_type = ssa->var_info[ssa_op->op2_use].type;
|
||||
}
|
||||
if (ssa_op->result_use >= 0) {
|
||||
opline->result_use_type = ssa->var_info[ssa_op->result_use].type;
|
||||
}
|
||||
if (ssa_op->op1_def >= 0) {
|
||||
opline->op1_def_type = ssa->var_info[ssa_op->op1_def].type;
|
||||
}
|
||||
if (ssa_op->op2_def >= 0) {
|
||||
opline->op2_def_type = ssa->var_info[ssa_op->op2_def].type;
|
||||
}
|
||||
if (ssa_op->result_def >= 0) {
|
||||
opline->result_def_type = ssa->var_info[ssa_op->result_def].type;
|
||||
}
|
||||
#endif
|
||||
zend_vm_set_opcode_handler_ex(opline, op1_info, op2_info, res_info);
|
||||
opline++;
|
||||
}
|
||||
|
@ -1549,19 +1444,6 @@ void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void
|
|||
zend_foreach_op_array_helper(op_array, func, context);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
zend_property_info *property;
|
||||
ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, property) {
|
||||
zend_function **hooks = property->hooks;
|
||||
if (property->ce == ce && property->hooks) {
|
||||
for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) {
|
||||
zend_function *hook = hooks[i];
|
||||
if (hook && hook->common.scope == ce && !(hooks[i]->op_array.fn_flags & ZEND_ACC_TRAIT_CLONE)) {
|
||||
zend_foreach_op_array_helper(&hooks[i]->op_array, func, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
|
||||
|
|
|
@ -98,10 +98,6 @@ ZEND_API int zend_optimizer_register_pass(zend_optimizer_pass_t pass);
|
|||
ZEND_API void zend_optimizer_unregister_pass(int idx);
|
||||
zend_result zend_optimizer_startup(void);
|
||||
zend_result zend_optimizer_shutdown(void);
|
||||
|
||||
typedef void (*zend_op_array_func_t)(zend_op_array *, void *context);
|
||||
void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void *context);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif
|
||||
|
|
|
@ -105,8 +105,6 @@ zend_class_entry *zend_optimizer_get_class_entry(
|
|||
const zend_script *script, const zend_op_array *op_array, zend_string *lcname);
|
||||
zend_class_entry *zend_optimizer_get_class_entry_from_op1(
|
||||
const zend_script *script, const zend_op_array *op_array, const zend_op *opline);
|
||||
const zend_class_constant *zend_fetch_class_const_info(
|
||||
const zend_script *script, const zend_op_array *op_array, const zend_op *opline, bool *is_prototype);
|
||||
|
||||
void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx);
|
||||
void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx);
|
||||
|
@ -128,4 +126,7 @@ int sccp_optimize_op_array(zend_optimizer_ctx *ctx, zend_op_array *op_array, zen
|
|||
int dce_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *optimizer_ctx, zend_ssa *ssa, bool reorder_dtor_effects);
|
||||
zend_result zend_ssa_escape_analysis(const zend_script *script, zend_op_array *op_array, zend_ssa *ssa);
|
||||
|
||||
typedef void (*zend_op_array_func_t)(zend_op_array *, void *context);
|
||||
void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void *context);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "zend_ssa.h"
|
||||
#include "zend_dump.h"
|
||||
#include "zend_inference.h"
|
||||
#include "zend_worklist.h"
|
||||
#include "Optimizer/zend_optimizer_internal.h"
|
||||
|
||||
static bool dominates(const zend_basic_block *blocks, int a, int b) {
|
||||
|
@ -608,7 +607,7 @@ add_op1_def:
|
|||
}
|
||||
break;
|
||||
case ZEND_ASSIGN_OBJ_REF:
|
||||
if ((build_flags & ZEND_SSA_RC_INFERENCE) && opline->op1_type == IS_CV) {
|
||||
if (opline->op1_type == IS_CV) {
|
||||
ssa_ops[k].op1_def = ssa_vars_count;
|
||||
var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
|
||||
ssa_vars_count++;
|
||||
|
@ -767,35 +766,6 @@ add_op1_def:
|
|||
//NEW_SSA_VAR(opline->op1.var)
|
||||
}
|
||||
break;
|
||||
case ZEND_FRAMELESS_ICALL_1:
|
||||
case ZEND_FRAMELESS_ICALL_2:
|
||||
case ZEND_FRAMELESS_ICALL_3: {
|
||||
if ((build_flags & ZEND_SSA_RC_INFERENCE) && opline->op1_type == IS_CV) {
|
||||
ssa_ops[k].op1_def = ssa_vars_count;
|
||||
var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
|
||||
ssa_vars_count++;
|
||||
//NEW_SSA_VAR(opline->op1.var)
|
||||
}
|
||||
if ((build_flags & ZEND_SSA_RC_INFERENCE) && opline->op2_type == IS_CV) {
|
||||
ssa_ops[k].op2_def = ssa_vars_count;
|
||||
var[EX_VAR_TO_NUM(opline->op2.var)] = ssa_vars_count;
|
||||
ssa_vars_count++;
|
||||
//NEW_SSA_VAR(opline->op2.var)
|
||||
}
|
||||
if (opline->opcode == ZEND_FRAMELESS_ICALL_3) {
|
||||
next = opline + 1;
|
||||
if (next->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
|
||||
ssa_ops[k + 1].op1_use = var[EX_VAR_TO_NUM(next->op1.var)];
|
||||
//USE_SSA_VAR(op_array->last_var + next->op1.var);
|
||||
if ((build_flags & ZEND_SSA_RC_INFERENCE) && next->op1_type == IS_CV) {
|
||||
ssa_ops[k + 1].op1_def = ssa_vars_count;
|
||||
var[EX_VAR_TO_NUM(next->op1.var)] = ssa_vars_count;
|
||||
ssa_vars_count++;
|
||||
//NEW_SSA_VAR(next->op1.var)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -817,7 +787,7 @@ ZEND_API int zend_ssa_rename_op(const zend_op_array *op_array, const zend_op *op
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static void zend_ssa_rename_in_block(const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, int *var, int n) /* {{{ */
|
||||
static zend_result zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, int *var, int n) /* {{{ */
|
||||
{
|
||||
zend_basic_block *blocks = ssa->cfg.blocks;
|
||||
zend_ssa_block *ssa_blocks = ssa->blocks;
|
||||
|
@ -825,6 +795,15 @@ static void zend_ssa_rename_in_block(const zend_op_array *op_array, uint32_t bui
|
|||
int ssa_vars_count = ssa->vars_count;
|
||||
int i, j;
|
||||
zend_op *opline, *end;
|
||||
int *tmp = NULL;
|
||||
ALLOCA_FLAG(use_heap = 0);
|
||||
|
||||
// FIXME: Can we optimize this copying out in some cases?
|
||||
if (blocks[n].next_child >= 0) {
|
||||
tmp = do_alloca(sizeof(int) * (op_array->last_var + op_array->T), use_heap);
|
||||
memcpy(tmp, var, sizeof(int) * (op_array->last_var + op_array->T));
|
||||
var = tmp;
|
||||
}
|
||||
|
||||
if (ssa_blocks[n].phis) {
|
||||
zend_ssa_phi *phi = ssa_blocks[n].phis;
|
||||
|
@ -908,90 +887,22 @@ static void zend_ssa_rename_in_block(const zend_op_array *op_array, uint32_t bui
|
|||
}
|
||||
|
||||
ssa->vars_count = ssa_vars_count;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_result zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, int *var, int n)
|
||||
{
|
||||
/* The worklist contains block numbers, encoded as positive or negative value.
|
||||
* Positive values indicate that the variable rename still needs to happen for the block.
|
||||
* Negative values indicate the variable rename was done and all children were handled too.
|
||||
* In that case, we will clean up.
|
||||
* Because block 0 is valid, we bias the block numbers by adding 1 such that we can distinguish
|
||||
* positive and negative values in all cases. */
|
||||
zend_worklist_stack work;
|
||||
ALLOCA_FLAG(work_use_heap);
|
||||
ZEND_WORKLIST_STACK_ALLOCA(&work, ssa->cfg.blocks_count, work_use_heap);
|
||||
zend_worklist_stack_push(&work, n + 1);
|
||||
|
||||
/* This is used to backtrack the right version of the renamed variables to use. */
|
||||
ALLOCA_FLAG(save_vars_use_heap);
|
||||
unsigned int save_vars_top = 0;
|
||||
int **save_vars = do_alloca(sizeof(int *) * (ssa->cfg.blocks_count + 1), save_vars_use_heap);
|
||||
save_vars[0] = var;
|
||||
|
||||
while (work.len) {
|
||||
n = zend_worklist_stack_pop(&work);
|
||||
|
||||
/* Enter state: perform SSA variable rename */
|
||||
if (n > 0) {
|
||||
n--;
|
||||
|
||||
// FIXME: Can we optimize this copying out in some cases?
|
||||
int *new_var;
|
||||
if (ssa->cfg.blocks[n].next_child >= 0) {
|
||||
new_var = emalloc(sizeof(int) * (op_array->last_var + op_array->T));
|
||||
memcpy(new_var, save_vars[save_vars_top], sizeof(int) * (op_array->last_var + op_array->T));
|
||||
save_vars[++save_vars_top] = new_var;
|
||||
} else {
|
||||
new_var = save_vars[save_vars_top];
|
||||
j = blocks[n].children;
|
||||
while (j >= 0) {
|
||||
// FIXME: Tail call optimization?
|
||||
if (zend_ssa_rename(op_array, build_flags, ssa, var, j) == FAILURE)
|
||||
return FAILURE;
|
||||
j = blocks[j].next_child;
|
||||
}
|
||||
|
||||
zend_ssa_rename_in_block(op_array, build_flags, ssa, new_var, n);
|
||||
|
||||
int j = ssa->cfg.blocks[n].children;
|
||||
if (j >= 0) {
|
||||
/* Push backtrack state */
|
||||
zend_worklist_stack_push(&work, -(n + 1));
|
||||
|
||||
/* Push children in enter state */
|
||||
unsigned int child_count = 0;
|
||||
int len_prior = work.len;
|
||||
do {
|
||||
zend_worklist_stack_push(&work, j + 1);
|
||||
j = ssa->cfg.blocks[j].next_child;
|
||||
child_count++;
|
||||
} while (j >= 0);
|
||||
|
||||
/* Reverse block order to maintain SSA variable number order given in previous PHP versions,
|
||||
* but the data structure doesn't allow reverse dominator tree traversal. */
|
||||
for (unsigned int i = 0; i < child_count / 2; i++) {
|
||||
int tmp = work.buf[len_prior + i];
|
||||
work.buf[len_prior + i] = work.buf[work.len - 1 - i];
|
||||
work.buf[work.len - 1 - i] = tmp;
|
||||
if (tmp) {
|
||||
free_alloca(tmp, use_heap);
|
||||
}
|
||||
} else {
|
||||
/* Leafs jump directly to backtracking */
|
||||
goto backtrack;
|
||||
}
|
||||
}
|
||||
/* Leave state: backtrack */
|
||||
else {
|
||||
n = -n;
|
||||
n--;
|
||||
backtrack:;
|
||||
if (ssa->cfg.blocks[n].next_child >= 0) {
|
||||
efree(save_vars[save_vars_top]);
|
||||
save_vars_top--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free_alloca(save_vars, save_vars_use_heap);
|
||||
ZEND_WORKLIST_STACK_FREE_ALLOCA(&work, work_use_heap);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API zend_result zend_build_ssa(zend_arena **arena, const zend_script *script, const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa) /* {{{ */
|
||||
{
|
||||
|
|
|
@ -67,7 +67,7 @@ struct _zend_ssa_phi {
|
|||
int var; /* Original CV, VAR or TMP variable index */
|
||||
int ssa_var; /* SSA variable index */
|
||||
int block; /* current BB index */
|
||||
bool has_range_constraint;
|
||||
bool has_range_constraint : 1;
|
||||
zend_ssa_phi **use_chains;
|
||||
zend_ssa_phi *sym_use_chain;
|
||||
int *sources; /* Array of SSA IDs that produce this var.
|
||||
|
@ -112,8 +112,8 @@ typedef struct _zend_ssa_var {
|
|||
zend_ssa_phi *definition_phi; /* phi that defines this value */
|
||||
zend_ssa_phi *phi_use_chain; /* uses of this value in Phi, linked through use_chain */
|
||||
zend_ssa_phi *sym_use_chain; /* uses of this value in Pi constraints */
|
||||
bool no_val : 1; /* value doesn't matter (used as op1 in ZEND_ASSIGN) */
|
||||
bool scc_entry : 1;
|
||||
unsigned int no_val : 1; /* value doesn't matter (used as op1 in ZEND_ASSIGN) */
|
||||
unsigned int scc_entry : 1;
|
||||
unsigned int alias : 2; /* value may be changed indirectly */
|
||||
unsigned int escape_state : 2;
|
||||
} zend_ssa_var;
|
||||
|
|
601
Zend/Zend.m4
601
Zend/Zend.m4
|
@ -4,12 +4,13 @@ dnl
|
|||
dnl ZEND_CHECK_FLOAT_PRECISION
|
||||
dnl
|
||||
dnl x87 floating point internal precision control checks
|
||||
dnl See: https://wiki.php.net/rfc/rounding
|
||||
dnl See: http://wiki.php.net/rfc/rounding
|
||||
dnl
|
||||
AC_DEFUN([ZEND_CHECK_FLOAT_PRECISION], [dnl
|
||||
AC_CACHE_CHECK([for usable _FPU_SETCW],
|
||||
[php_cv_have__fpu_setcw],
|
||||
[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <fpu_control.h>], [dnl
|
||||
AC_DEFUN([ZEND_CHECK_FLOAT_PRECISION],[
|
||||
AC_MSG_CHECKING([for usable _FPU_SETCW])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <fpu_control.h>
|
||||
]],[[
|
||||
fpu_control_t fpu_oldcw, fpu_cw;
|
||||
volatile double result;
|
||||
double a = 2877.0;
|
||||
|
@ -20,17 +21,18 @@ AC_CACHE_CHECK([for usable _FPU_SETCW],
|
|||
_FPU_SETCW(fpu_cw);
|
||||
result = a / b;
|
||||
_FPU_SETCW(fpu_oldcw);
|
||||
(void)result;
|
||||
])],
|
||||
[php_cv_have__fpu_setcw=yes],
|
||||
[php_cv_have__fpu_setcw=no])])
|
||||
AS_VAR_IF([php_cv_have__fpu_setcw], [yes],
|
||||
[AC_DEFINE([HAVE__FPU_SETCW], [1],
|
||||
[Define to 1 if _FPU_SETCW is present and usable.])])
|
||||
]])],[ac_cfp_have__fpu_setcw=yes],[ac_cfp_have__fpu_setcw=no])
|
||||
if test "$ac_cfp_have__fpu_setcw" = "yes" ; then
|
||||
AC_DEFINE(HAVE__FPU_SETCW, 1, [whether _FPU_SETCW is present and usable])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for usable fpsetprec],
|
||||
[php_cv_have_fpsetprec],
|
||||
[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <machine/ieeefp.h>], [dnl
|
||||
AC_MSG_CHECKING([for usable fpsetprec])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <machine/ieeefp.h>
|
||||
]],[[
|
||||
fp_prec_t fpu_oldprec;
|
||||
volatile double result;
|
||||
double a = 2877.0;
|
||||
|
@ -40,17 +42,18 @@ AC_CACHE_CHECK([for usable fpsetprec],
|
|||
fpsetprec(FP_PD);
|
||||
result = a / b;
|
||||
fpsetprec(fpu_oldprec);
|
||||
(void)result;
|
||||
])],
|
||||
[php_cv_have_fpsetprec=yes],
|
||||
[php_cv_have_fpsetprec=no])])
|
||||
AS_VAR_IF([php_cv_have_fpsetprec], [yes],
|
||||
[AC_DEFINE([HAVE_FPSETPREC], [1],
|
||||
[Define to 1 if fpsetprec is present and usable.])])
|
||||
]])], [ac_cfp_have_fpsetprec=yes], [ac_cfp_have_fpsetprec=no])
|
||||
if test "$ac_cfp_have_fpsetprec" = "yes" ; then
|
||||
AC_DEFINE(HAVE_FPSETPREC, 1, [whether fpsetprec is present and usable])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for usable _controlfp],
|
||||
[php_cv_have__controlfp],
|
||||
[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <float.h>], [dnl
|
||||
AC_MSG_CHECKING([for usable _controlfp])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <float.h>
|
||||
]],[[
|
||||
unsigned int fpu_oldcw;
|
||||
volatile double result;
|
||||
double a = 2877.0;
|
||||
|
@ -60,17 +63,18 @@ AC_CACHE_CHECK([for usable _controlfp],
|
|||
_controlfp(_PC_53, _MCW_PC);
|
||||
result = a / b;
|
||||
_controlfp(fpu_oldcw, _MCW_PC);
|
||||
(void)result;
|
||||
])],
|
||||
[php_cv_have__controlfp=yes],
|
||||
[php_cv_have__controlfp=no])])
|
||||
AS_VAR_IF([php_cv_have__controlfp], [yes],
|
||||
[AC_DEFINE([HAVE__CONTROLFP], [1],
|
||||
[Define to 1 if _controlfp is present and usable.])])
|
||||
]])], [ac_cfp_have__controlfp=yes], [ac_cfp_have__controlfp=no])
|
||||
if test "$ac_cfp_have__controlfp" = "yes" ; then
|
||||
AC_DEFINE(HAVE__CONTROLFP, 1, [whether _controlfp is present usable])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for usable _controlfp_s],
|
||||
[php_cv_have__controlfp_s],
|
||||
[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <float.h>], [dnl
|
||||
AC_MSG_CHECKING([for usable _controlfp_s])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <float.h>
|
||||
]],[[
|
||||
unsigned int fpu_oldcw, fpu_cw;
|
||||
volatile double result;
|
||||
double a = 2877.0;
|
||||
|
@ -81,17 +85,18 @@ AC_CACHE_CHECK([for usable _controlfp_s],
|
|||
_controlfp_s(&fpu_cw, _PC_53, _MCW_PC);
|
||||
result = a / b;
|
||||
_controlfp_s(&fpu_cw, fpu_oldcw, _MCW_PC);
|
||||
(void)result;
|
||||
])],
|
||||
[php_cv_have__controlfp_s=yes],
|
||||
[php_cv_have__controlfp_s=no])])
|
||||
AS_VAR_IF([php_cv_have__controlfp_s], [yes],
|
||||
[AC_DEFINE([HAVE__CONTROLFP_S], [1],
|
||||
[Define to 1 if _controlfp_s is present and usable.])])
|
||||
]])], [ac_cfp_have__controlfp_s=yes], [ac_cfp_have__controlfp_s=no])
|
||||
if test "$ac_cfp_have__controlfp_s" = "yes" ; then
|
||||
AC_DEFINE(HAVE__CONTROLFP_S, 1, [whether _controlfp_s is present and usable])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([whether FPU control word can be manipulated by inline assembler],
|
||||
[php_cv_have_fpu_inline_asm_x86],
|
||||
[AC_LINK_IFELSE([AC_LANG_PROGRAM([], [dnl
|
||||
AC_MSG_CHECKING([whether FPU control word can be manipulated by inline assembler])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
/* nothing */
|
||||
]],[[
|
||||
unsigned int oldcw, cw;
|
||||
volatile double result;
|
||||
double a = 2877.0;
|
||||
|
@ -100,185 +105,235 @@ AC_CACHE_CHECK([whether FPU control word can be manipulated by inline assembler]
|
|||
__asm__ __volatile__ ("fnstcw %0" : "=m" (*&oldcw));
|
||||
cw = (oldcw & ~0x0 & ~0x300) | 0x200;
|
||||
__asm__ __volatile__ ("fldcw %0" : : "m" (*&cw));
|
||||
|
||||
result = a / b;
|
||||
|
||||
__asm__ __volatile__ ("fldcw %0" : : "m" (*&oldcw));
|
||||
(void)result;
|
||||
])],
|
||||
[php_cv_have_fpu_inline_asm_x86=yes],
|
||||
[php_cv_have_fpu_inline_asm_x86=no])])
|
||||
AS_VAR_IF([php_cv_have_fpu_inline_asm_x86], [yes],
|
||||
[AC_DEFINE([HAVE_FPU_INLINE_ASM_X86], [1],
|
||||
[Define to 1 if FPU control word can be manipulated by inline assembler.])])
|
||||
]])], [ac_cfp_have_fpu_inline_asm_x86=yes], [ac_cfp_have_fpu_inline_asm_x86=no])
|
||||
if test "$ac_cfp_have_fpu_inline_asm_x86" = "yes" ; then
|
||||
AC_DEFINE(HAVE_FPU_INLINE_ASM_X86, 1, [whether FPU control word can be manipulated by inline assembler])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl ZEND_DLSYM_CHECK
|
||||
dnl LIBZEND_BASIC_CHECKS
|
||||
dnl
|
||||
dnl Basic checks specific for the Zend engine library.
|
||||
dnl
|
||||
AC_DEFUN([LIBZEND_BASIC_CHECKS],[
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
|
||||
AC_CHECK_HEADERS([cpuid.h])
|
||||
|
||||
dnl
|
||||
dnl LIBZEND_DLSYM_CHECK
|
||||
dnl
|
||||
dnl Ugly hack to check if dlsym() requires a leading underscore in symbol name.
|
||||
dnl
|
||||
AC_DEFUN([ZEND_DLSYM_CHECK], [dnl
|
||||
AC_DEFUN([LIBZEND_DLSYM_CHECK],[
|
||||
AC_MSG_CHECKING([whether dlsym() requires a leading underscore in symbol names])
|
||||
_LT_AC_TRY_DLOPEN_SELF([AC_MSG_RESULT([no])], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([DLSYM_NEEDS_UNDERSCORE], [1],
|
||||
[Define to 1 if 'dlsym()' requires a leading underscore in symbol names.])
|
||||
], [AC_MSG_RESULT([no])], [])
|
||||
_LT_AC_TRY_DLOPEN_SELF([
|
||||
AC_MSG_RESULT(no)
|
||||
], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(DLSYM_NEEDS_UNDERSCORE, 1, [Define if dlsym() requires a leading underscore in symbol names. ])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
], [])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl ZEND_INIT
|
||||
dnl
|
||||
dnl Configure checks and initialization specific for the Zend engine library.
|
||||
dnl
|
||||
AC_DEFUN([ZEND_INIT], [dnl
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
dnl Checks for library functions.
|
||||
AC_CHECK_FUNCS(getpid kill sigsetjmp pthread_getattr_np pthread_attr_get_np pthread_get_stackaddr_np pthread_attr_getstack pthread_stackseg_np gettid)
|
||||
|
||||
AC_CHECK_HEADERS(m4_normalize([
|
||||
cpuid.h
|
||||
libproc.h
|
||||
]))
|
||||
dnl Test whether the stack grows downwards
|
||||
dnl Assumes contiguous stack
|
||||
AC_MSG_CHECKING(whether the stack grows downwards)
|
||||
|
||||
dnl Check for library functions.
|
||||
AC_CHECK_FUNCS(m4_normalize([
|
||||
getpid
|
||||
gettid
|
||||
kill
|
||||
mremap
|
||||
pthread_attr_get_np
|
||||
pthread_attr_getstack
|
||||
pthread_get_stackaddr_np
|
||||
pthread_getattr_np
|
||||
pthread_stackseg_np
|
||||
strnlen
|
||||
]))
|
||||
|
||||
AC_CHECK_DECL([clock_gettime_nsec_np],
|
||||
[AC_DEFINE([HAVE_CLOCK_GETTIME_NSEC_NP], [1],
|
||||
[Define to 1 if you have the declaration of 'clock_gettime_nsec_np'.])],,
|
||||
[#include <time.h>])
|
||||
|
||||
dnl
|
||||
dnl Check for sigsetjmp. If sigsetjmp is defined as a macro, use AC_CHECK_DECL
|
||||
dnl as a fallback since AC_CHECK_FUNC cannot detect macros.
|
||||
dnl
|
||||
AC_CHECK_FUNC([sigsetjmp],,
|
||||
[AC_CHECK_DECL([sigsetjmp],,
|
||||
[AC_MSG_FAILURE([Required sigsetjmp not found.])],
|
||||
[#include <setjmp.h>])])
|
||||
|
||||
ZEND_CHECK_STACK_DIRECTION
|
||||
ZEND_CHECK_FLOAT_PRECISION
|
||||
ZEND_DLSYM_CHECK
|
||||
ZEND_CHECK_GLOBAL_REGISTER_VARIABLES
|
||||
ZEND_CHECK_CPUID_COUNT
|
||||
|
||||
AC_MSG_CHECKING([whether to enable thread safety])
|
||||
AC_MSG_RESULT([$ZEND_ZTS])
|
||||
AS_VAR_IF([ZEND_ZTS], [yes], [
|
||||
AC_DEFINE([ZTS], [1], [Define to 1 if thread safety (ZTS) is enabled.])
|
||||
AS_VAR_APPEND([CFLAGS], [" -DZTS"])
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([whether to enable Zend debugging])
|
||||
AC_MSG_RESULT([$ZEND_DEBUG])
|
||||
AH_TEMPLATE([ZEND_DEBUG],
|
||||
[Define to 1 if debugging is enabled, and to 0 if not.])
|
||||
AS_VAR_IF([ZEND_DEBUG], [yes], [
|
||||
AC_DEFINE([ZEND_DEBUG], [1])
|
||||
echo " $CFLAGS" | grep ' -g' >/dev/null || CFLAGS="$CFLAGS -g"
|
||||
], [AC_DEFINE([ZEND_DEBUG], [0])])
|
||||
|
||||
AS_VAR_IF([GCC], [yes],
|
||||
[CFLAGS="-Wall -Wextra -Wno-unused-parameter -Wno-sign-compare $CFLAGS"])
|
||||
|
||||
dnl Check if compiler supports -Wno-clobbered (only GCC).
|
||||
AX_CHECK_COMPILE_FLAG([-Wno-clobbered],
|
||||
[CFLAGS="-Wno-clobbered $CFLAGS"])
|
||||
dnl Check for support for implicit fallthrough level 1, also add after previous
|
||||
dnl CFLAGS as level 3 is enabled in -Wextra.
|
||||
AX_CHECK_COMPILE_FLAG([-Wimplicit-fallthrough=1],
|
||||
[CFLAGS="$CFLAGS -Wimplicit-fallthrough=1"])
|
||||
AX_CHECK_COMPILE_FLAG([-Wduplicated-cond],
|
||||
[CFLAGS="-Wduplicated-cond $CFLAGS"])
|
||||
AX_CHECK_COMPILE_FLAG([-Wlogical-op],
|
||||
[CFLAGS="-Wlogical-op $CFLAGS"])
|
||||
AX_CHECK_COMPILE_FLAG([-Wformat-truncation],
|
||||
[CFLAGS="-Wformat-truncation $CFLAGS"])
|
||||
AX_CHECK_COMPILE_FLAG([-Wstrict-prototypes],
|
||||
[CFLAGS="-Wstrict-prototypes $CFLAGS"])
|
||||
AX_CHECK_COMPILE_FLAG([-fno-common],
|
||||
[CFLAGS="-fno-common $CFLAGS"])
|
||||
|
||||
ZEND_CHECK_ALIGNMENT
|
||||
ZEND_CHECK_SIGNALS
|
||||
ZEND_CHECK_MAX_EXECUTION_TIMERS
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl ZEND_CHECK_STACK_DIRECTION
|
||||
dnl
|
||||
dnl Check whether the stack grows downwards, assumes contiguous stack.
|
||||
dnl
|
||||
AC_DEFUN([ZEND_CHECK_STACK_DIRECTION],
|
||||
[AC_CACHE_CHECK([whether the stack grows downwards],
|
||||
[php_cv_have_stack_limit],
|
||||
[AC_RUN_IFELSE([AC_LANG_SOURCE([dnl
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __has_builtin
|
||||
# if __has_builtin(__builtin_frame_address)
|
||||
# define builtin_frame_address __builtin_frame_address(0)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
int (*volatile f)(uintptr_t);
|
||||
|
||||
int stack_grows_downwards(uintptr_t arg) {
|
||||
#ifdef builtin_frame_address
|
||||
uintptr_t addr = (uintptr_t)builtin_frame_address;
|
||||
#else
|
||||
int local;
|
||||
uintptr_t addr = (uintptr_t)&local;
|
||||
#endif
|
||||
|
||||
return addr < arg;
|
||||
return (uintptr_t)&local < arg;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
#ifdef builtin_frame_address
|
||||
uintptr_t addr = (uintptr_t)builtin_frame_address;
|
||||
#else
|
||||
int local;
|
||||
uintptr_t addr = (uintptr_t)&local;
|
||||
#endif
|
||||
|
||||
f = stack_grows_downwards;
|
||||
return f(addr) ? 0 : 1;
|
||||
}])],
|
||||
[php_cv_have_stack_limit=yes],
|
||||
[php_cv_have_stack_limit=no],
|
||||
[php_cv_have_stack_limit=no])])
|
||||
AS_VAR_IF([php_cv_have_stack_limit], [yes],
|
||||
[AC_DEFINE([ZEND_CHECK_STACK_LIMIT], [1],
|
||||
[Define to 1 if checking the stack limit is supported.])])
|
||||
return f((uintptr_t)&local) ? 0 : 1;
|
||||
}
|
||||
]])], [
|
||||
AC_DEFINE([ZEND_CHECK_STACK_LIMIT], 1, [Define if checking the stack limit is supported])
|
||||
AC_MSG_RESULT(yes)
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
||||
ZEND_CHECK_FLOAT_PRECISION
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl ZEND_CHECK_GLOBAL_REGISTER_VARIABLES
|
||||
dnl LIBZEND_OTHER_CHECKS
|
||||
dnl
|
||||
dnl Check whether to enable global register variables if supported.
|
||||
dnl
|
||||
AC_DEFUN([ZEND_CHECK_GLOBAL_REGISTER_VARIABLES], [dnl
|
||||
AC_DEFUN([LIBZEND_OTHER_CHECKS],[
|
||||
|
||||
AC_MSG_CHECKING(whether to enable thread-safety)
|
||||
AC_MSG_RESULT($ZEND_ZTS)
|
||||
|
||||
AC_MSG_CHECKING(whether to enable Zend debugging)
|
||||
AC_MSG_RESULT($ZEND_DEBUG)
|
||||
|
||||
if test "$ZEND_DEBUG" = "yes"; then
|
||||
AC_DEFINE(ZEND_DEBUG,1,[ ])
|
||||
echo " $CFLAGS" | grep ' -g' >/dev/null || DEBUG_CFLAGS="-g"
|
||||
if test "$CFLAGS" = "-g -O2"; then
|
||||
CFLAGS=-g
|
||||
fi
|
||||
else
|
||||
AC_DEFINE(ZEND_DEBUG,0,[ ])
|
||||
fi
|
||||
|
||||
test -n "$GCC" && CFLAGS="-Wall -Wextra -Wno-unused-parameter -Wno-sign-compare $CFLAGS"
|
||||
dnl Check if compiler supports -Wno-clobbered (only GCC)
|
||||
AX_CHECK_COMPILE_FLAG([-Wno-clobbered], CFLAGS="-Wno-clobbered $CFLAGS", , [-Werror])
|
||||
dnl Check for support for implicit fallthrough level 1, also add after previous CFLAGS as level 3 is enabled in -Wextra
|
||||
AX_CHECK_COMPILE_FLAG([-Wimplicit-fallthrough=1], CFLAGS="$CFLAGS -Wimplicit-fallthrough=1", , [-Werror])
|
||||
AX_CHECK_COMPILE_FLAG([-Wduplicated-cond], CFLAGS="-Wduplicated-cond $CFLAGS", , [-Werror])
|
||||
AX_CHECK_COMPILE_FLAG([-Wlogical-op], CFLAGS="-Wlogical-op $CFLAGS", , [-Werror])
|
||||
AX_CHECK_COMPILE_FLAG([-Wformat-truncation], CFLAGS="-Wformat-truncation $CFLAGS", , [-Werror])
|
||||
AX_CHECK_COMPILE_FLAG([-Wstrict-prototypes], CFLAGS="-Wstrict-prototypes $CFLAGS", , [-Werror])
|
||||
AX_CHECK_COMPILE_FLAG([-fno-common], CFLAGS="-fno-common $CFLAGS", , [-Werror])
|
||||
|
||||
test -n "$DEBUG_CFLAGS" && CFLAGS="$CFLAGS $DEBUG_CFLAGS"
|
||||
|
||||
if test "$ZEND_ZTS" = "yes"; then
|
||||
AC_DEFINE(ZTS,1,[ ])
|
||||
CFLAGS="$CFLAGS -DZTS"
|
||||
fi
|
||||
|
||||
AC_C_INLINE
|
||||
|
||||
AC_MSG_CHECKING(target system is Darwin)
|
||||
if echo "$target" | grep "darwin" > /dev/null; then
|
||||
AC_DEFINE([DARWIN], 1, [Define if the target system is darwin])
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
dnl Test and set the alignment define for ZEND_MM. This also does the
|
||||
dnl logarithmic test for ZEND_MM.
|
||||
AC_MSG_CHECKING(for MM alignment and log values)
|
||||
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef union _mm_align_test {
|
||||
void *ptr;
|
||||
double dbl;
|
||||
long lng;
|
||||
} mm_align_test;
|
||||
|
||||
#if (defined (__GNUC__) && __GNUC__ >= 2)
|
||||
#define ZEND_MM_ALIGNMENT (__alignof__ (mm_align_test))
|
||||
#else
|
||||
#define ZEND_MM_ALIGNMENT (sizeof(mm_align_test))
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
size_t i = ZEND_MM_ALIGNMENT;
|
||||
int zeros = 0;
|
||||
FILE *fp;
|
||||
|
||||
while (i & ~0x1) {
|
||||
zeros++;
|
||||
i = i >> 1;
|
||||
}
|
||||
|
||||
fp = fopen("conftest.zend", "w");
|
||||
fprintf(fp, "(size_t)%zu (size_t)%d %d\n", ZEND_MM_ALIGNMENT, zeros, ZEND_MM_ALIGNMENT < 4);
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
]])], [
|
||||
LIBZEND_MM_ALIGN=`cat conftest.zend | cut -d ' ' -f 1`
|
||||
LIBZEND_MM_ALIGN_LOG2=`cat conftest.zend | cut -d ' ' -f 2`
|
||||
LIBZEND_MM_NEED_EIGHT_BYTE_REALIGNMENT=`cat conftest.zend | cut -d ' ' -f 3`
|
||||
AC_DEFINE_UNQUOTED(ZEND_MM_ALIGNMENT, $LIBZEND_MM_ALIGN, [ ])
|
||||
AC_DEFINE_UNQUOTED(ZEND_MM_ALIGNMENT_LOG2, $LIBZEND_MM_ALIGN_LOG2, [ ])
|
||||
AC_DEFINE_UNQUOTED(ZEND_MM_NEED_EIGHT_BYTE_REALIGNMENT, $LIBZEND_MM_NEED_EIGHT_BYTE_REALIGNMENT, [ ])
|
||||
], [], [
|
||||
dnl Cross compilation needs something here.
|
||||
AC_DEFINE(ZEND_MM_ALIGNMENT, 8, [ ])
|
||||
AC_DEFINE(ZEND_MM_ALIGNMENT_LOG2, 3, [ ])
|
||||
AC_DEFINE(ZEND_MM_NEED_EIGHT_BYTE_REALIGNMENT, 0, [ ])
|
||||
])
|
||||
|
||||
AC_MSG_RESULT(done)
|
||||
|
||||
AC_CHECK_FUNCS(mremap)
|
||||
|
||||
AC_ARG_ENABLE([zend-signals],
|
||||
[AS_HELP_STRING([--disable-zend-signals],
|
||||
[whether to enable zend signal handling])],
|
||||
[ZEND_SIGNALS=$enableval],
|
||||
[ZEND_SIGNALS=yes])
|
||||
|
||||
AC_CHECK_FUNCS([sigaction], [], [
|
||||
ZEND_SIGNALS=no
|
||||
])
|
||||
if test "$ZEND_SIGNALS" = "yes"; then
|
||||
AC_DEFINE(ZEND_SIGNALS, 1, [Use zend signal handling])
|
||||
CFLAGS="$CFLAGS -DZEND_SIGNALS"
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(whether to enable zend signal handling)
|
||||
AC_MSG_RESULT($ZEND_SIGNALS)
|
||||
|
||||
dnl Don't enable Zend Max Execution Timers by default until PHP 8.3 to not break the ABI
|
||||
AC_ARG_ENABLE([zend-max-execution-timers],
|
||||
[AS_HELP_STRING([--enable-zend-max-execution-timers],
|
||||
[whether to enable zend max execution timers])],
|
||||
[ZEND_MAX_EXECUTION_TIMERS=$enableval],
|
||||
[ZEND_MAX_EXECUTION_TIMERS=$ZEND_ZTS])
|
||||
|
||||
AS_CASE(["$host_alias"], [*linux*], [], [ZEND_MAX_EXECUTION_TIMERS='no'])
|
||||
|
||||
PHP_CHECK_FUNC(timer_create, rt)
|
||||
if test "$ac_cv_func_timer_create" != "yes"; then
|
||||
ZEND_MAX_EXECUTION_TIMERS='no'
|
||||
fi
|
||||
|
||||
if test "$ZEND_MAX_EXECUTION_TIMERS" = "yes"; then
|
||||
AC_DEFINE(ZEND_MAX_EXECUTION_TIMERS, 1, [Use zend max execution timers])
|
||||
CFLAGS="$CFLAGS -DZEND_MAX_EXECUTION_TIMERS"
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(whether to enable zend max execution timers)
|
||||
AC_MSG_RESULT($ZEND_MAX_EXECUTION_TIMERS)
|
||||
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE([gcc-global-regs],
|
||||
[AS_HELP_STRING([--disable-gcc-global-regs],
|
||||
[Disable GCC global register variables])],
|
||||
[whether to enable GCC global register variables])],
|
||||
[ZEND_GCC_GLOBAL_REGS=$enableval],
|
||||
[ZEND_GCC_GLOBAL_REGS=yes])
|
||||
|
||||
AS_VAR_IF([ZEND_GCC_GLOBAL_REGS], [no],,
|
||||
[AC_CACHE_CHECK([whether system supports global register variables],
|
||||
[php_cv_have_global_register_vars],
|
||||
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
|
||||
AC_MSG_CHECKING(for global register variables support)
|
||||
if test "$ZEND_GCC_GLOBAL_REGS" != "no"; then
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
#if defined(__GNUC__)
|
||||
# define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
|
||||
#else
|
||||
|
@ -316,151 +371,31 @@ int emu(const opcode_handler_t *ip, void *fp) {
|
|||
while ((*ip)());
|
||||
FP = orig_fp;
|
||||
IP = orig_ip;
|
||||
}], [])],
|
||||
[php_cv_have_global_register_vars=yes],
|
||||
[php_cv_have_global_register_vars=no])
|
||||
])
|
||||
AS_VAR_IF([php_cv_have_global_register_vars], [yes],
|
||||
[AC_DEFINE([HAVE_GCC_GLOBAL_REGS], [1],
|
||||
[Define to 1 if the target system has support for global register
|
||||
variables.])],
|
||||
[ZEND_GCC_GLOBAL_REGS=no])
|
||||
])
|
||||
AC_MSG_CHECKING([whether to enable global register variables support])
|
||||
AC_MSG_RESULT([$ZEND_GCC_GLOBAL_REGS])
|
||||
}
|
||||
]], [[
|
||||
]])], [
|
||||
ZEND_GCC_GLOBAL_REGS=yes
|
||||
], [
|
||||
ZEND_GCC_GLOBAL_REGS=no
|
||||
])
|
||||
fi
|
||||
if test "$ZEND_GCC_GLOBAL_REGS" = "yes"; then
|
||||
AC_DEFINE([HAVE_GCC_GLOBAL_REGS], 1, [Define if the target system has support for global register variables])
|
||||
fi
|
||||
AC_MSG_RESULT($ZEND_GCC_GLOBAL_REGS)
|
||||
|
||||
dnl
|
||||
dnl ZEND_CHECK_CPUID_COUNT
|
||||
dnl
|
||||
dnl Check whether __cpuid_count is available.
|
||||
dnl
|
||||
AC_DEFUN([ZEND_CHECK_CPUID_COUNT],
|
||||
[AC_CACHE_CHECK([whether __cpuid_count is available],
|
||||
[php_cv_have___cpuid_count],
|
||||
[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <cpuid.h>], [dnl
|
||||
AC_CACHE_CHECK(whether __cpuid_count is available, ac_cv_cpuid_count_available, [
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <cpuid.h>
|
||||
]], [[
|
||||
unsigned eax, ebx, ecx, edx;
|
||||
__cpuid_count(0, 0, eax, ebx, ecx, edx);
|
||||
])],
|
||||
[php_cv_have___cpuid_count=yes],
|
||||
[php_cv_have___cpuid_count=no])])
|
||||
AS_VAR_IF([php_cv_have___cpuid_count], [yes],
|
||||
[AC_DEFINE([HAVE_CPUID_COUNT], [1],
|
||||
[Define to 1 if '__cpuid_count' is available.])])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl ZEND_CHECK_ALIGNMENT
|
||||
dnl
|
||||
dnl Test and set the alignment defines for the Zend memory manager (ZEND_MM).
|
||||
dnl This also does the logarithmic test.
|
||||
dnl
|
||||
AC_DEFUN([ZEND_CHECK_ALIGNMENT],
|
||||
[AC_CACHE_CHECK([for Zend memory manager alignment and log values],
|
||||
[php_cv_align_mm],
|
||||
[AC_RUN_IFELSE([AC_LANG_SOURCE([
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef union _mm_align_test {
|
||||
void *ptr;
|
||||
double dbl;
|
||||
long lng;
|
||||
} mm_align_test;
|
||||
|
||||
#if (defined (__GNUC__) && __GNUC__ >= 2)
|
||||
#define ZEND_MM_ALIGNMENT (__alignof__ (mm_align_test))
|
||||
#else
|
||||
#define ZEND_MM_ALIGNMENT (sizeof(mm_align_test))
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
size_t i = ZEND_MM_ALIGNMENT;
|
||||
int zeros = 0;
|
||||
FILE *fp;
|
||||
|
||||
while (i & ~0x1) {
|
||||
zeros++;
|
||||
i = i >> 1;
|
||||
}
|
||||
|
||||
fp = fopen("conftest.zend", "w");
|
||||
fprintf(fp, "(size_t)%zu (size_t)%d %d\n",
|
||||
ZEND_MM_ALIGNMENT, zeros, ZEND_MM_ALIGNMENT < 4);
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
])],
|
||||
[php_cv_align_mm=$(cat conftest.zend)],
|
||||
[php_cv_align_mm=failed],
|
||||
[php_cv_align_mm="(size_t)8 (size_t)3 0"])])
|
||||
AS_VAR_IF([php_cv_align_mm], [failed],
|
||||
[AC_MSG_FAILURE([ZEND_MM alignment defines failed.])],
|
||||
[zend_mm_alignment=$(echo $php_cv_align_mm | cut -d ' ' -f 1)
|
||||
zend_mm_alignment_log2=$(echo $php_cv_align_mm | cut -d ' ' -f 2)
|
||||
zend_mm_8byte_realign=$(echo $php_cv_align_mm | cut -d ' ' -f 3)
|
||||
AC_DEFINE_UNQUOTED([ZEND_MM_ALIGNMENT],
|
||||
[$zend_mm_alignment],
|
||||
[Number of bytes for the ZEND_MM alignment.])
|
||||
AC_DEFINE_UNQUOTED([ZEND_MM_ALIGNMENT_LOG2],
|
||||
[$zend_mm_alignment_log2],
|
||||
[Number of bytes for the logarithmic ZEND_MM alignment.])
|
||||
AC_DEFINE_UNQUOTED([ZEND_MM_NEED_EIGHT_BYTE_REALIGNMENT],
|
||||
[$zend_mm_8byte_realign],
|
||||
[Define to 1 if ZEND_MM needs 8-byte realignment, and to 0 if not.])
|
||||
])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl ZEND_CHECK_SIGNALS
|
||||
dnl
|
||||
dnl Check whether to enable Zend signal handling if supported by the system.
|
||||
dnl
|
||||
AC_DEFUN([ZEND_CHECK_SIGNALS], [dnl
|
||||
AC_ARG_ENABLE([zend-signals],
|
||||
[AS_HELP_STRING([--disable-zend-signals],
|
||||
[Disable Zend signal handling])],
|
||||
[ZEND_SIGNALS=$enableval],
|
||||
[ZEND_SIGNALS=yes])
|
||||
|
||||
AC_CHECK_FUNCS([sigaction],, [ZEND_SIGNALS=no])
|
||||
AS_VAR_IF([ZEND_SIGNALS], [yes],
|
||||
[AC_DEFINE([ZEND_SIGNALS], [1],
|
||||
[Define to 1 if Zend signal handling is supported and enabled.])
|
||||
AS_VAR_APPEND([CFLAGS], [" -DZEND_SIGNALS"])])
|
||||
|
||||
AC_MSG_CHECKING([whether to enable Zend signal handling])
|
||||
AC_MSG_RESULT([$ZEND_SIGNALS])
|
||||
])
|
||||
|
||||
dnl
|
||||
dnl ZEND_CHECK_MAX_EXECUTION_TIMERS
|
||||
dnl
|
||||
dnl Check whether to enable Zend max execution timers.
|
||||
dnl
|
||||
AC_DEFUN([ZEND_CHECK_MAX_EXECUTION_TIMERS], [dnl
|
||||
AC_ARG_ENABLE([zend-max-execution-timers],
|
||||
[AS_HELP_STRING([--enable-zend-max-execution-timers],
|
||||
[Enable Zend max execution timers; when building with thread safety
|
||||
(--enable-zts), they are automatically enabled by default based on the
|
||||
system support])],
|
||||
[ZEND_MAX_EXECUTION_TIMERS=$enableval],
|
||||
[ZEND_MAX_EXECUTION_TIMERS=$ZEND_ZTS])
|
||||
|
||||
AS_CASE([$host_alias], [*linux*|*freebsd*],,
|
||||
[ZEND_MAX_EXECUTION_TIMERS=no])
|
||||
|
||||
AS_VAR_IF([ZEND_MAX_EXECUTION_TIMERS], [yes],
|
||||
[AC_SEARCH_LIBS([timer_create], [rt],,
|
||||
[ZEND_MAX_EXECUTION_TIMERS=no])])
|
||||
|
||||
AS_VAR_IF([ZEND_MAX_EXECUTION_TIMERS], [yes],
|
||||
[AC_DEFINE([ZEND_MAX_EXECUTION_TIMERS], [1],
|
||||
[Define to 1 if Zend max execution timers are supported and enabled.])
|
||||
AS_VAR_APPEND([CFLAGS], [" -DZEND_MAX_EXECUTION_TIMERS"])])
|
||||
|
||||
AC_MSG_CHECKING([whether to enable Zend max execution timers])
|
||||
AC_MSG_RESULT([$ZEND_MAX_EXECUTION_TIMERS])
|
||||
])
|
||||
]])], [
|
||||
ac_cv_cpuid_count_available=yes
|
||||
], [
|
||||
ac_cv_cpuid_count_available=no
|
||||
])])
|
||||
if test "$ac_cv_cpuid_count_available" = "yes"; then
|
||||
AC_DEFINE([HAVE_CPUID_COUNT], 1, [whether __cpuid_count is available])
|
||||
fi
|
||||
|
|
|
@ -24,10 +24,6 @@
|
|||
* *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifdef __x86_64__
|
||||
#include "jump_x86_64_sysv_elf_gas.S"
|
||||
#else
|
||||
|
||||
.file "jump_i386_sysv_elf_gas.S"
|
||||
.text
|
||||
.globl jump_fcontext
|
||||
|
@ -95,5 +91,3 @@ jump_fcontext:
|
|||
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 8 | 16 | 24 | *
|
||||
* ------------------------------------------------- *
|
||||
* | FS0 | FS1 | FS2 | FS3 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 40 | 48 | 56 | *
|
||||
* ------------------------------------------------- *
|
||||
* | FS4 | FS5 | FS6 | FS7 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | 72 | 80 | 88 | *
|
||||
* ------------------------------------------------- *
|
||||
* | S0 | S1 | S2 | S3 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
|
||||
* ------------------------------------------------- *
|
||||
* | S4 | S5 | S6 | S7 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
|
||||
* ------------------------------------------------- *
|
||||
* | S8 | FP | RA | PC | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
* *****************************************************/
|
||||
|
||||
.file "jump_loongarch64_sysv_elf_gas.S"
|
||||
.text
|
||||
.globl jump_fcontext
|
||||
.align 2
|
||||
.type jump_fcontext,@function
|
||||
jump_fcontext:
|
||||
# reserve space on stack
|
||||
addi.d $sp, $sp, -160
|
||||
|
||||
# save fs0 - fs7
|
||||
fst.d $fs0, $sp, 0
|
||||
fst.d $fs1, $sp, 8
|
||||
fst.d $fs2, $sp, 16
|
||||
fst.d $fs3, $sp, 24
|
||||
fst.d $fs4, $sp, 32
|
||||
fst.d $fs5, $sp, 40
|
||||
fst.d $fs6, $sp, 48
|
||||
fst.d $fs7, $sp, 56
|
||||
|
||||
# save s0 - s8, fp, ra
|
||||
st.d $s0, $sp, 64
|
||||
st.d $s1, $sp, 72
|
||||
st.d $s2, $sp, 80
|
||||
st.d $s3, $sp, 88
|
||||
st.d $s4, $sp, 96
|
||||
st.d $s5, $sp, 104
|
||||
st.d $s6, $sp, 112
|
||||
st.d $s7, $sp, 120
|
||||
st.d $s8, $sp, 128
|
||||
st.d $fp, $sp, 136
|
||||
st.d $ra, $sp, 144
|
||||
|
||||
# save RA as PC
|
||||
st.d $ra, $sp, 152
|
||||
|
||||
# store SP (pointing to context-data) in A2
|
||||
move $a2, $sp
|
||||
|
||||
# restore SP (pointing to context-data) from A0
|
||||
move $sp, $a0
|
||||
|
||||
# load fs0 - fs7
|
||||
fld.d $fs0, $sp, 0
|
||||
fld.d $fs1, $sp, 8
|
||||
fld.d $fs2, $sp, 16
|
||||
fld.d $fs3, $sp, 24
|
||||
fld.d $fs4, $sp, 32
|
||||
fld.d $fs5, $sp, 40
|
||||
fld.d $fs6, $sp, 48
|
||||
fld.d $fs7, $sp, 56
|
||||
|
||||
#load s0 - s7
|
||||
ld.d $s0, $sp, 64
|
||||
ld.d $s1, $sp, 72
|
||||
ld.d $s2, $sp, 80
|
||||
ld.d $s3, $sp, 88
|
||||
ld.d $s4, $sp, 96
|
||||
ld.d $s5, $sp, 104
|
||||
ld.d $s6, $sp, 112
|
||||
ld.d $s7, $sp, 120
|
||||
ld.d $s8, $sp, 128
|
||||
ld.d $fp, $sp, 136
|
||||
ld.d $ra, $sp, 144
|
||||
|
||||
# return transfer_t from jump
|
||||
# pass transfer_t as first arg in context function
|
||||
# a0 == FCTX, a1 == DATA
|
||||
move $a0, $a2
|
||||
|
||||
# load PC
|
||||
ld.d $a2, $sp, 152
|
||||
|
||||
# restore stack
|
||||
addi.d $sp, $sp, 160
|
||||
|
||||
# jump to context
|
||||
jr $a2
|
||||
.size jump_fcontext, .-jump_fcontext
|
||||
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
Copyright Claudio Jeker 2024
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
/*
|
||||
* typedef struct {
|
||||
* void *handle;
|
||||
* zend_fiber_transfer *transfer;
|
||||
* } boost_context_data;
|
||||
*
|
||||
* boost_context_data jump_fcontext(void *to, zend_fiber_transfer *transfer);
|
||||
*/
|
||||
#define CC64FSZ 176
|
||||
#define BIAS 2047
|
||||
#define SP 128
|
||||
#define I7 136
|
||||
|
||||
.file "jump_sparc64_sysv_elf_gas.S"
|
||||
.text
|
||||
.align 4
|
||||
.global jump_fcontext
|
||||
.type jump_fcontext, %function
|
||||
jump_fcontext:
|
||||
# prepare stack
|
||||
save %sp, -CC64FSZ, %sp
|
||||
|
||||
# store framepointer and return address in slots reserved
|
||||
# for arguments
|
||||
stx %fp, [%sp + BIAS + SP]
|
||||
stx %i7, [%sp + BIAS + I7]
|
||||
mov %sp, %o0
|
||||
# force flush register windows to stack and with that save context
|
||||
flushw
|
||||
# get SP (pointing to new context-data) from %i0 param
|
||||
mov %i0, %sp
|
||||
# load framepointer and return address from context
|
||||
ldx [%sp + BIAS + SP], %fp
|
||||
ldx [%sp + BIAS + I7], %i7
|
||||
|
||||
ret
|
||||
restore %o0, %g0, %o0
|
||||
# restore old %sp (pointing to old context-data) in %o0
|
||||
# *data stored in %o1 was not modified
|
||||
.size jump_fcontext,.-jump_fcontext
|
||||
# Mark that we don't need executable stack.
|
||||
.section .note.GNU-stack,"",%progbits
|
|
@ -1,205 +0,0 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
Copyright Thomas Sailer 2013.
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
/*************************************************************************************
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | SEE registers (XMM6-XMM15) | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | SEE registers (XMM6-XMM15) | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0xe40 | 0x44 | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | SEE registers (XMM6-XMM15) | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x60 | 0x64 | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | SEE registers (XMM6-XMM15) | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 32 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x80 | 0x84 | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | SEE registers (XMM6-XMM15) | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0xa0 | 0xa4 | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | fc_mxcsr|fc_x87_cw| <alignment> | fbr_strg | fc_dealloc | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0xc0 | 0xc4 | 0xc8 | 0xcc | 0xd0 | 0xd4 | 0xd8 | 0xdc | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | limit | base | R12 | R13 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0xe0 | 0xe4 | 0xe8 | 0xec | 0xf0 | 0xf4 | 0xf8 | 0xfc | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | R14 | R15 | RDI | RSI | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x100 | 0x104 | 0x108 | 0x10c | 0x110 | 0x114 | 0x118 | 0x11c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | RBX | RBP | hidden | RIP | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x120 | 0x124 | 0x128 | 0x12c | 0x130 | 0x134 | 0x138 | 0x13c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | parameter area | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x140 | 0x144 | 0x148 | 0x14c | 0x150 | 0x154 | 0x158 | 0x15c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | FCTX | DATA | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
**************************************************************************************/
|
||||
|
||||
.file "jump_x86_64_ms_pe_gas.asm"
|
||||
.text
|
||||
.p2align 4,,15
|
||||
.def jump_fcontext; .scl 2; .type 32; .endef
|
||||
.seh_proc jump_fcontext
|
||||
jump_fcontext:
|
||||
.seh_endprologue
|
||||
|
||||
leaq -0x118(%rsp), %rsp /* prepare stack */
|
||||
|
||||
#if !defined(BOOST_USE_TSX)
|
||||
/* save XMM storage */
|
||||
movaps %xmm6, 0x0(%rsp)
|
||||
movaps %xmm7, 0x10(%rsp)
|
||||
movaps %xmm8, 0x20(%rsp)
|
||||
movaps %xmm9, 0x30(%rsp)
|
||||
movaps %xmm10, 0x40(%rsp)
|
||||
movaps %xmm11, 0x50(%rsp)
|
||||
movaps %xmm12, 0x60(%rsp)
|
||||
movaps %xmm13, 0x70(%rsp)
|
||||
movaps %xmm14, 0x80(%rsp)
|
||||
movaps %xmm15, 0x90(%rsp)
|
||||
stmxcsr 0xa0(%rsp) /* save MMX control- and status-word */
|
||||
fnstcw 0xa4(%rsp) /* save x87 control-word */
|
||||
#endif
|
||||
|
||||
/* load NT_TIB */
|
||||
movq %gs:(0x30), %r10
|
||||
/* save fiber local storage */
|
||||
movq 0x20(%r10), %rax
|
||||
movq %rax, 0xb0(%rsp)
|
||||
/* save current deallocation stack */
|
||||
movq 0x1478(%r10), %rax
|
||||
movq %rax, 0xb8(%rsp)
|
||||
/* save current stack limit */
|
||||
movq 0x10(%r10), %rax
|
||||
movq %rax, 0xc0(%rsp)
|
||||
/* save current stack base */
|
||||
movq 0x08(%r10), %rax
|
||||
movq %rax, 0xc8(%rsp)
|
||||
|
||||
movq %r12, 0xd0(%rsp) /* save R12 */
|
||||
movq %r13, 0xd8(%rsp) /* save R13 */
|
||||
movq %r14, 0xe0(%rsp) /* save R14 */
|
||||
movq %r15, 0xe8(%rsp) /* save R15 */
|
||||
movq %rdi, 0xf0(%rsp) /* save RDI */
|
||||
movq %rsi, 0xf8(%rsp) /* save RSI */
|
||||
movq %rbx, 0x100(%rsp) /* save RBX */
|
||||
movq %rbp, 0x108(%rsp) /* save RBP */
|
||||
|
||||
movq %rcx, 0x110(%rsp) /* save hidden address of transport_t */
|
||||
|
||||
/* preserve RSP (pointing to context-data) in R9 */
|
||||
movq %rsp, %r9
|
||||
|
||||
/* restore RSP (pointing to context-data) from RDX */
|
||||
movq %rdx, %rsp
|
||||
|
||||
#if !defined(BOOST_USE_TSX)
|
||||
/* restore XMM storage */
|
||||
movaps 0x0(%rsp), %xmm6
|
||||
movaps 0x10(%rsp), %xmm7
|
||||
movaps 0x20(%rsp), %xmm8
|
||||
movaps 0x30(%rsp), %xmm9
|
||||
movaps 0x40(%rsp), %xmm10
|
||||
movaps 0x50(%rsp), %xmm11
|
||||
movaps 0x60(%rsp), %xmm12
|
||||
movaps 0x70(%rsp), %xmm13
|
||||
movaps 0x80(%rsp), %xmm14
|
||||
movaps 0x90(%rsp), %xmm15
|
||||
ldmxcsr 0xa0(%rsp) /* restore MMX control- and status-word */
|
||||
fldcw 0xa4(%rsp) /* restore x87 control-word */
|
||||
#endif
|
||||
|
||||
/* load NT_TIB */
|
||||
movq %gs:(0x30), %r10
|
||||
/* restore fiber local storage */
|
||||
movq 0xb0(%rsp), %rax
|
||||
movq %rax, 0x20(%r10)
|
||||
/* restore current deallocation stack */
|
||||
movq 0xb8(%rsp), %rax
|
||||
movq %rax, 0x1478(%r10)
|
||||
/* restore current stack limit */
|
||||
movq 0xc0(%rsp), %rax
|
||||
movq %rax, 0x10(%r10)
|
||||
/* restore current stack base */
|
||||
movq 0xc8(%rsp), %rax
|
||||
movq %rax, 0x08(%r10)
|
||||
|
||||
movq 0xd0(%rsp), %r12 /* restore R12 */
|
||||
movq 0xd8(%rsp), %r13 /* restore R13 */
|
||||
movq 0xe0(%rsp), %r14 /* restore R14 */
|
||||
movq 0xe8(%rsp), %r15 /* restore R15 */
|
||||
movq 0xf0(%rsp), %rdi /* restore RDI */
|
||||
movq 0xf8(%rsp), %rsi /* restore RSI */
|
||||
movq 0x100(%rsp), %rbx /* restore RBX */
|
||||
movq 0x108(%rsp), %rbp /* restore RBP */
|
||||
|
||||
movq 0x110(%rsp), %rax /* restore hidden address of transport_t */
|
||||
|
||||
leaq 0x118(%rsp), %rsp /* prepare stack */
|
||||
|
||||
/* restore return-address */
|
||||
popq %r10
|
||||
|
||||
/* transport_t returned in RAX */
|
||||
/* return parent fcontext_t */
|
||||
movq %r9, 0x0(%rax)
|
||||
/* return data */
|
||||
movq %r8, 0x8(%rax)
|
||||
|
||||
/* transport_t as 1.arg of context-function */
|
||||
movq %rax, %rcx
|
||||
|
||||
/* indirect jump to context */
|
||||
jmp *%r10
|
||||
.seh_endproc
|
|
@ -31,9 +31,6 @@
|
|||
* *
|
||||
****************************************************************************************/
|
||||
|
||||
# ifdef __i386__
|
||||
# include "jump_i386_sysv_elf_gas.S"
|
||||
# else
|
||||
# if defined __CET__
|
||||
# include <cet.h>
|
||||
# define SHSTK_ENABLED (__CET__ & 0x2)
|
||||
|
@ -151,4 +148,3 @@ jump_fcontext:
|
|||
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
# endif
|
||||
|
|
|
@ -24,10 +24,6 @@
|
|||
* *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifdef __x86_64__
|
||||
#include "make_x86_64_sysv_elf_gas.S"
|
||||
#else
|
||||
|
||||
.file "make_i386_sysv_elf_gas.S"
|
||||
.text
|
||||
.globl make_fcontext
|
||||
|
@ -115,5 +111,3 @@ finish:
|
|||
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
/*******************************************************
|
||||
* *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 0 | 8 | 16 | 24 | *
|
||||
* ------------------------------------------------- *
|
||||
* | FS0 | FS1 | FS2 | FS3 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 40 | 48 | 56 | *
|
||||
* ------------------------------------------------- *
|
||||
* | FS4 | FS5 | FS6 | FS7 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 64 | 72 | 80 | 88 | *
|
||||
* ------------------------------------------------- *
|
||||
* | S0 | S1 | S2 | S3 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 96 | 100 | 104 | 108 | 112 | 116 | 120 | 124 | *
|
||||
* ------------------------------------------------- *
|
||||
* | S4 | S5 | S6 | S7 | *
|
||||
* ------------------------------------------------- *
|
||||
* ------------------------------------------------- *
|
||||
* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
|
||||
* ------------------------------------------------- *
|
||||
* | 128 | 132 | 136 | 140 | 144 | 148 | 152 | 156 | *
|
||||
* ------------------------------------------------- *
|
||||
* | S8 | FP | RA | PC | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
* *****************************************************/
|
||||
|
||||
.file "make_loongarch64_sysv_elf_gas.S"
|
||||
.text
|
||||
.globl make_fcontext
|
||||
.align 2
|
||||
.type make_fcontext,@function
|
||||
make_fcontext:
|
||||
# shift address in A0 to lower 16 byte boundary
|
||||
bstrins.d $a0, $zero, 3, 0
|
||||
|
||||
# reserve space for context-data on context-stack
|
||||
addi.d $a0, $a0, -160
|
||||
|
||||
# third arg of make_fcontext() == address of context-function
|
||||
st.d $a2, $a0, 152
|
||||
|
||||
# save address of finish as return-address for context-function
|
||||
# will be entered after context-function returns
|
||||
la.local $a4, finish
|
||||
st.d $a4, $a0, 144
|
||||
|
||||
# return pointer to context-data
|
||||
jr $ra
|
||||
|
||||
finish:
|
||||
# exit code is zero
|
||||
li.d $a0, 0
|
||||
# call _exit(0)
|
||||
b %plt(_exit)
|
||||
|
||||
.size make_fcontext, .-make_fcontext
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
|
@ -64,7 +64,6 @@
|
|||
* | FCTX | DATA | | | *
|
||||
* ------------------------------------------------- *
|
||||
* *
|
||||
*******************************************************/
|
||||
|
||||
.text
|
||||
.globl _make_fcontext
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
Copyright Claudio Jeker 2024
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
/*
|
||||
* void *make_fcontext(void *sp, size_t size, void (*fn)(boost_context_data));
|
||||
*/
|
||||
#define CC64FSZ 176
|
||||
#define BIAS 2047
|
||||
#define FP 112
|
||||
#define SP 128
|
||||
#define I7 136
|
||||
|
||||
.file "make_sparc64_sysv_elf_gas.S"
|
||||
.text
|
||||
.align 4
|
||||
.global make_fcontext
|
||||
.type make_fcontext, %function
|
||||
make_fcontext:
|
||||
save %sp, -CC64FSZ, %sp
|
||||
|
||||
# shift address in %i0 (allocated stack) to lower 16 byte boundary
|
||||
and %i0, -0xf, %i0
|
||||
|
||||
# reserve space for two frames on the stack
|
||||
# the first frame is for the call the second one holds the data
|
||||
# for jump_fcontext
|
||||
sub %i0, 2 * CC64FSZ, %i0
|
||||
|
||||
# third argument of make_fcontext() is the context-function to call
|
||||
# store it in the first stack frame, also clear %fp there to indicate
|
||||
# the end of the stack.
|
||||
stx %i2, [%i0 + CC64FSZ + I7]
|
||||
stx %g0, [%i0 + CC64FSZ + FP]
|
||||
|
||||
# On OpenBSD stackghost prevents overriding the return address on
|
||||
# a stack frame. So this code uses an extra trampoline to load
|
||||
# to call the context-function and then do the _exit(0) dance.
|
||||
# Extract the full address of the trampoline via pc relative addressing
|
||||
1:
|
||||
rd %pc, %l0
|
||||
add %l0, (trampoline - 1b - 8), %l0
|
||||
stx %l0, [%i0 + I7]
|
||||
|
||||
# Save framepointer to first stack frame but first substract the BIAS
|
||||
add %i0, CC64FSZ - BIAS, %l0
|
||||
stx %l0, [%i0 + SP]
|
||||
|
||||
# Return context-data which is also includes the BIAS
|
||||
ret
|
||||
restore %i0, -BIAS, %o0
|
||||
|
||||
trampoline:
|
||||
ldx [%sp + BIAS + I7], %l0
|
||||
|
||||
# no need to setup boost_context_data, already in %o0 and %o1
|
||||
jmpl %l0, %o7
|
||||
nop
|
||||
|
||||
call _exit
|
||||
clr %o0
|
||||
unimp
|
||||
.size make_fcontext,.-make_fcontext
|
||||
# Mark that we don't need executable stack.
|
||||
.section .note.GNU-stack,"",%progbits
|
|
@ -1,170 +0,0 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
Copyright Thomas Sailer 2013.
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
/*************************************************************************************
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | SEE registers (XMM6-XMM15) | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | SEE registers (XMM6-XMM15) | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0xe40 | 0x44 | 0x48 | 0x4c | 0x50 | 0x54 | 0x58 | 0x5c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | SEE registers (XMM6-XMM15) | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x60 | 0x64 | 0x68 | 0x6c | 0x70 | 0x74 | 0x78 | 0x7c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | SEE registers (XMM6-XMM15) | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 32 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x80 | 0x84 | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | SEE registers (XMM6-XMM15) | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0xa0 | 0xa4 | 0xa8 | 0xac | 0xb0 | 0xb4 | 0xb8 | 0xbc | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | fc_mxcsr|fc_x87_cw| <alignment> | fbr_strg | fc_dealloc | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0xc0 | 0xc4 | 0xc8 | 0xcc | 0xd0 | 0xd4 | 0xd8 | 0xdc | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | limit | base | R12 | R13 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0xe0 | 0xe4 | 0xe8 | 0xec | 0xf0 | 0xf4 | 0xf8 | 0xfc | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | R14 | R15 | RDI | RSI | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x100 | 0x104 | 0x108 | 0x10c | 0x110 | 0x114 | 0x118 | 0x11c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | RBX | RBP | hidden | RIP | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x120 | 0x124 | 0x128 | 0x12c | 0x130 | 0x134 | 0x138 | 0x13c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | parameter area | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x140 | 0x144 | 0x148 | 0x14c | 0x150 | 0x154 | 0x158 | 0x15c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | FCTX | DATA | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
**************************************************************************************/
|
||||
|
||||
.file "make_x86_64_ms_pe_gas.asm"
|
||||
.text
|
||||
.p2align 4,,15
|
||||
.def make_fcontext; .scl 2; .type 32; .endef
|
||||
.seh_proc make_fcontext
|
||||
make_fcontext:
|
||||
.seh_endprologue
|
||||
|
||||
/* first arg of make_fcontext() == top of context-stack */
|
||||
movq %rcx, %rax
|
||||
|
||||
/* shift address in RAX to lower 16 byte boundary */
|
||||
/* == pointer to fcontext_t and address of context stack */
|
||||
andq $-16, %rax
|
||||
|
||||
/* reserve space for context-data on context-stack */
|
||||
/* on context-function entry: (RSP -0x8) % 16 == 0 */
|
||||
leaq -0x150(%rax), %rax
|
||||
|
||||
/* third arg of make_fcontext() == address of context-function */
|
||||
movq %r8, 0x100(%rax)
|
||||
|
||||
/* first arg of make_fcontext() == top of context-stack */
|
||||
/* save top address of context stack as 'base' */
|
||||
movq %rcx, 0xc8(%rax)
|
||||
/* second arg of make_fcontext() == size of context-stack */
|
||||
/* negate stack size for LEA instruction (== substraction) */
|
||||
negq %rdx
|
||||
/* compute bottom address of context stack (limit) */
|
||||
leaq (%rcx,%rdx), %rcx
|
||||
/* save bottom address of context stack as 'limit' */
|
||||
movq %rcx, 0xc0(%rax)
|
||||
/* save address of context stack limit as 'dealloction stack' */
|
||||
movq %rcx, 0xb8(%rax)
|
||||
/* set fiber-storage to zero */
|
||||
xorq %rcx, %rcx
|
||||
movq %rcx, 0xb0(%rax)
|
||||
|
||||
/* save MMX control- and status-word */
|
||||
stmxcsr 0xa0(%rax)
|
||||
/* save x87 control-word */
|
||||
fnstcw 0xa4(%rax)
|
||||
|
||||
/* compute address of transport_t */
|
||||
leaq 0x140(%rax), %rcx
|
||||
/* store address of transport_t in hidden field */
|
||||
movq %rcx, 0x110(%rax)
|
||||
|
||||
/* compute abs address of label trampoline */
|
||||
leaq trampoline(%rip), %rcx
|
||||
/* save address of finish as return-address for context-function */
|
||||
/* will be entered after jump_fcontext() first time */
|
||||
movq %rcx, 0x118(%rax)
|
||||
|
||||
/* compute abs address of label finish */
|
||||
leaq finish(%rip), %rcx
|
||||
/* save address of finish as return-address for context-function */
|
||||
/* will be entered after context-function returns */
|
||||
movq %rcx, 0x108(%rax)
|
||||
|
||||
ret /* return pointer to context-data */
|
||||
|
||||
trampoline:
|
||||
/* store return address on stack */
|
||||
/* fix stack alignment */
|
||||
pushq %rbp
|
||||
/* jump to context-function */
|
||||
jmp *%rbx
|
||||
|
||||
finish:
|
||||
/* 32byte shadow-space for _exit() */
|
||||
andq $-32, %rsp
|
||||
/* 32byte shadow-space for _exit() are */
|
||||
/* already reserved by make_fcontext() */
|
||||
/* exit code is zero */
|
||||
xorq %rcx, %rcx
|
||||
/* exit application */
|
||||
call _exit
|
||||
hlt
|
||||
.seh_endproc
|
||||
|
||||
.def _exit; .scl 2; .type 32; .endef /* standard C library function */
|
|
@ -31,9 +31,6 @@
|
|||
* *
|
||||
****************************************************************************************/
|
||||
|
||||
# ifdef __i386__
|
||||
# include "make_i386_sysv_elf_gas.S"
|
||||
# else
|
||||
# if defined __CET__
|
||||
# include <cet.h>
|
||||
# define SHSTK_ENABLED (__CET__ & 0x2)
|
||||
|
@ -187,4 +184,3 @@ finish:
|
|||
|
||||
/* Mark that we don't need executable stack. */
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
# endif
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
.code
|
||||
|
||||
; ZEND_API void execute_ex(zend_execute_data *ex)
|
||||
PUBLIC execute_ex
|
||||
|
||||
EXTERN execute_ex_real:PROC
|
||||
|
||||
; Assembly wrapper around the real execute_ex function, so that we can
|
||||
; save the preserved registers when re-entering the VM from JIT code.
|
||||
; See GH-18136.
|
||||
execute_ex PROC EXPORT FRAME
|
||||
; 10 floating points numbers
|
||||
; 32 bytes shadow space
|
||||
; 8 bytes to align after the return address
|
||||
sub rsp, 8*10 + 32 + 8
|
||||
.allocstack 8*10 + 32 + 8
|
||||
.endprolog
|
||||
movsd qword ptr [rsp + 32 + 8*0], xmm6
|
||||
movsd qword ptr [rsp + 32 + 8*1], xmm7
|
||||
movsd qword ptr [rsp + 32 + 8*2], xmm8
|
||||
movsd qword ptr [rsp + 32 + 8*3], xmm9
|
||||
movsd qword ptr [rsp + 32 + 8*4], xmm10
|
||||
movsd qword ptr [rsp + 32 + 8*5], xmm11
|
||||
movsd qword ptr [rsp + 32 + 8*6], xmm12
|
||||
movsd qword ptr [rsp + 32 + 8*7], xmm13
|
||||
movsd qword ptr [rsp + 32 + 8*8], xmm14
|
||||
movsd qword ptr [rsp + 32 + 8*9], xmm15
|
||||
call execute_ex_real
|
||||
movsd xmm6, qword ptr [rsp + 32 + 8*0]
|
||||
movsd xmm7, qword ptr [rsp + 32 + 8*1]
|
||||
movsd xmm8, qword ptr [rsp + 32 + 8*2]
|
||||
movsd xmm9, qword ptr [rsp + 32 + 8*3]
|
||||
movsd xmm10, qword ptr [rsp + 32 + 8*4]
|
||||
movsd xmm11, qword ptr [rsp + 32 + 8*5]
|
||||
movsd xmm12, qword ptr [rsp + 32 + 8*6]
|
||||
movsd xmm13, qword ptr [rsp + 32 + 8*7]
|
||||
movsd xmm14, qword ptr [rsp + 32 + 8*8]
|
||||
movsd xmm15, qword ptr [rsp + 32 + 8*9]
|
||||
add rsp, 8*10 + 32 + 8
|
||||
ret
|
||||
execute_ex ENDP
|
||||
|
||||
END
|
121
Zend/tests/002.phpt
Normal file
121
Zend/tests/002.phpt
Normal file
|
@ -0,0 +1,121 @@
|
|||
--TEST--
|
||||
func_get_arg() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function test1() {
|
||||
try {
|
||||
var_dump(func_get_arg(-10));
|
||||
} catch (\ValueError $e) {
|
||||
echo $e->getMessage() . \PHP_EOL;
|
||||
}
|
||||
|
||||
try {
|
||||
var_dump(func_get_arg(0));
|
||||
} catch (\Error $e) {
|
||||
echo $e->getMessage() . \PHP_EOL;
|
||||
}
|
||||
try {
|
||||
var_dump(func_get_arg(1));
|
||||
} catch (\Error $e) {
|
||||
echo $e->getMessage() . \PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
function test2($a) {
|
||||
try {
|
||||
var_dump(func_get_arg(0));
|
||||
} catch (\Error $e) {
|
||||
echo $e->getMessage() . \PHP_EOL;
|
||||
}
|
||||
try {
|
||||
var_dump(func_get_arg(1));
|
||||
} catch (\Error $e) {
|
||||
echo $e->getMessage() . \PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
function test3($a, $b) {
|
||||
try {
|
||||
var_dump(func_get_arg(0));
|
||||
} catch (\Error $e) {
|
||||
echo $e->getMessage() . \PHP_EOL;
|
||||
}
|
||||
try {
|
||||
var_dump(func_get_arg(1));
|
||||
} catch (\Error $e) {
|
||||
echo $e->getMessage() . \PHP_EOL;
|
||||
}
|
||||
try {
|
||||
var_dump(func_get_arg(2));
|
||||
} catch (\Error $e) {
|
||||
echo $e->getMessage() . \PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
test1();
|
||||
test1(10);
|
||||
test2(1);
|
||||
try {
|
||||
test2();
|
||||
} catch (Throwable $e) {
|
||||
echo "Exception: " . $e->getMessage() . "\n";
|
||||
}
|
||||
test3(1,2);
|
||||
|
||||
call_user_func("test1");
|
||||
try {
|
||||
call_user_func("test3", 1);
|
||||
} catch (Throwable $e) {
|
||||
echo "Exception: " . $e->getMessage() . "\n";
|
||||
}
|
||||
call_user_func("test3", 1, 2);
|
||||
|
||||
class test {
|
||||
static function test1($a) {
|
||||
try {
|
||||
var_dump(func_get_arg(0));
|
||||
} catch (\Error $e) {
|
||||
echo $e->getMessage() . \PHP_EOL;
|
||||
}
|
||||
try {
|
||||
var_dump(func_get_arg(1));
|
||||
} catch (\Error $e) {
|
||||
echo $e->getMessage() . \PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test::test1(1);
|
||||
try {
|
||||
var_dump(func_get_arg(1));
|
||||
} catch (\Error $e) {
|
||||
echo $e->getMessage() . \PHP_EOL;
|
||||
}
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
func_get_arg(): Argument #1 ($position) must be greater than or equal to 0
|
||||
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
|
||||
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
|
||||
func_get_arg(): Argument #1 ($position) must be greater than or equal to 0
|
||||
int(10)
|
||||
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
|
||||
int(1)
|
||||
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
|
||||
Exception: Too few arguments to function test2(), 0 passed in %s002.php on line %d and exactly 1 expected
|
||||
int(1)
|
||||
int(2)
|
||||
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
|
||||
func_get_arg(): Argument #1 ($position) must be greater than or equal to 0
|
||||
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
|
||||
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
|
||||
Exception: Too few arguments to function test3(), 1 passed in %s on line %d and exactly 2 expected
|
||||
int(1)
|
||||
int(2)
|
||||
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
|
||||
int(1)
|
||||
func_get_arg(): Argument #1 ($position) must be less than the number of the arguments passed to the currently executed function
|
||||
func_get_arg() cannot be called from the global scope
|
||||
Done
|
82
Zend/tests/003.phpt
Normal file
82
Zend/tests/003.phpt
Normal file
|
@ -0,0 +1,82 @@
|
|||
--TEST--
|
||||
func_get_args() tests
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function test1() {
|
||||
var_dump(func_get_args());
|
||||
}
|
||||
|
||||
function test2($a) {
|
||||
var_dump(func_get_args());
|
||||
}
|
||||
|
||||
function test3($a, $b) {
|
||||
var_dump(func_get_args());
|
||||
}
|
||||
|
||||
test1();
|
||||
test1(10);
|
||||
test2(1);
|
||||
try {
|
||||
test2();
|
||||
} catch (Throwable $e) {
|
||||
echo "Exception: " . $e->getMessage() . "\n";
|
||||
}
|
||||
test3(1,2);
|
||||
|
||||
call_user_func("test1");
|
||||
try {
|
||||
call_user_func("test3", 1);
|
||||
} catch (Throwable $e) {
|
||||
echo "Exception: " . $e->getMessage() . "\n";
|
||||
}
|
||||
call_user_func("test3", 1, 2);
|
||||
|
||||
class test {
|
||||
static function test1($a) {
|
||||
var_dump(func_get_args());
|
||||
}
|
||||
}
|
||||
|
||||
test::test1(1);
|
||||
|
||||
try {
|
||||
var_dump(func_get_args());
|
||||
} catch (\Error $e) {
|
||||
echo $e->getMessage() . \PHP_EOL;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(0) {
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(10)
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
}
|
||||
Exception: Too few arguments to function test2(), 0 passed in %s003.php on line %d and exactly 1 expected
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(1)
|
||||
[1]=>
|
||||
int(2)
|
||||
}
|
||||
array(0) {
|
||||
}
|
||||
Exception: Too few arguments to function test3(), 1 passed in %s003.php on line %d and exactly 2 expected
|
||||
array(2) {
|
||||
[0]=>
|
||||
int(1)
|
||||
[1]=>
|
||||
int(2)
|
||||
}
|
||||
array(1) {
|
||||
[0]=>
|
||||
int(1)
|
||||
}
|
||||
func_get_args() cannot be called from the global scope
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue