Compare commits

..

1 commit

Author SHA1 Message Date
Jakub Zelenka
4d0d451702
Update versions for PHP 8.3.24 2025-07-29 17:48:33 +02:00
10620 changed files with 760333 additions and 1077507 deletions

View file

@ -46,6 +46,8 @@ jobs:
libicu-dev \ libicu-dev \
libtidy-dev \ libtidy-dev \
libenchant-2-dev \ libenchant-2-dev \
libaspell-dev \
libpspell-dev \
libsasl2-dev \ libsasl2-dev \
libxpm-dev \ libxpm-dev \
libzip-dev \ libzip-dev \
@ -53,6 +55,8 @@ jobs:
libsqlite3-dev \ libsqlite3-dev \
libwebp-dev \ libwebp-dev \
libonig-dev \ libonig-dev \
libkrb5-dev \
libgssapi-krb5-2 \
libcurl4-openssl-dev \ libcurl4-openssl-dev \
libxml2-dev \ libxml2-dev \
libxslt1-dev \ libxslt1-dev \
@ -67,6 +71,7 @@ jobs:
`#snmp-mibs-downloader` \ `#snmp-mibs-downloader` \
freetds-dev \ freetds-dev \
`#unixodbc-dev` \ `#unixodbc-dev` \
libc-client-dev \
dovecot-core \ dovecot-core \
dovecot-pop3d \ dovecot-pop3d \
dovecot-imapd \ dovecot-imapd \
@ -90,6 +95,7 @@ jobs:
--prefix=/usr \ --prefix=/usr \
--enable-phpdbg \ --enable-phpdbg \
--enable-fpm \ --enable-fpm \
--enable-opcache \
--with-pdo-mysql=mysqlnd \ --with-pdo-mysql=mysqlnd \
--with-mysqli=mysqlnd \ --with-mysqli=mysqlnd \
--with-pgsql \ --with-pgsql \
@ -105,6 +111,7 @@ jobs:
--enable-exif \ --enable-exif \
--with-zip \ --with-zip \
--with-zlib \ --with-zlib \
--with-zlib-dir=/usr \
--enable-soap \ --enable-soap \
--enable-xmlreader \ --enable-xmlreader \
--with-xsl \ --with-xsl \
@ -124,7 +131,9 @@ jobs:
--enable-bcmath \ --enable-bcmath \
--enable-calendar \ --enable-calendar \
--enable-ftp \ --enable-ftp \
--with-pspell=/usr \
--with-enchant=/usr \ --with-enchant=/usr \
--with-kerberos \
--enable-sysvmsg \ --enable-sysvmsg \
--with-ffi \ --with-ffi \
--enable-zend-test \ --enable-zend-test \
@ -143,7 +152,12 @@ jobs:
--with-qdbm \ --with-qdbm \
--with-snmp \ --with-snmp \
`#--with-unixODBC` \ `#--with-unixODBC` \
--with-imap \
--with-kerberos \
--with-imap-ssl \
`#--with-pdo-odbc=unixODBC,/usr` \ `#--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-path=/etc \
--with-config-file-scan-dir=/etc/php.d \ --with-config-file-scan-dir=/etc/php.d \
--with-pdo-firebird \ --with-pdo-firebird \
@ -167,8 +181,9 @@ jobs:
no_output_timeout: 30m no_output_timeout: 30m
command: | command: |
sapi/cli/php run-tests.php \ sapi/cli/php run-tests.php \
-d zend_extension=opcache.so \
-d opcache.enable_cli=1 \ -d opcache.enable_cli=1 \
-d opcache.jit_buffer_size=64M \ -d opcache.jit_buffer_size=16M \
-d opcache.jit=tracing \ -d opcache.jit=tracing \
-d zend_test.observer.enabled=1 \ -d zend_test.observer.enabled=1 \
-d zend_test.observer.show_output=0 \ -d zend_test.observer.show_output=0 \

View file

@ -32,7 +32,3 @@ max_line_length = 80
[*.patch] [*.patch]
trim_trailing_whitespace = false trim_trailing_whitespace = false
[*.rst]
indent_style = space
max_line_length = 100

7
.gitattributes vendored
View file

@ -21,14 +21,9 @@
# Collapse generated files within git and pull request diff. # Collapse generated files within git and pull request diff.
**/*_arginfo.h linguist-generated -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_execute.h linguist-generated -diff
/Zend/zend_vm_handlers.h linguist-generated -diff /Zend/zend_vm_handlers.h linguist-generated -diff
/Zend/zend_vm_opcodes.[ch] 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 /ext/date/tests/ossfuzz*.txt binary
# Vendored libraries
/ext/lexbor/lexbor linguist-vendored
/ext/uri/uriparser linguist-vendored

5
.github/CODEOWNERS vendored
View file

@ -16,7 +16,7 @@
/.github @TimWolla /.github @TimWolla
/build/gen_stub.php @kocsismate /build/gen_stub.php @kocsismate
/ext/bcmath @nielsdos @SakiTakamachi /ext/bcmath @Girgias @nielsdos @SakiTakamachi
/ext/curl @adoy /ext/curl @adoy
/ext/date @derickr /ext/date @derickr
/ext/dba @Girgias /ext/dba @Girgias
@ -25,9 +25,9 @@
/ext/gd @devnexen /ext/gd @devnexen
/ext/gettext @devnexen /ext/gettext @devnexen
/ext/gmp @Girgias /ext/gmp @Girgias
/ext/imap @Girgias
/ext/intl @devnexen /ext/intl @devnexen
/ext/json @bukka /ext/json @bukka
/ext/lexbor @kocsismate @nielsdos
/ext/libxml @nielsdos /ext/libxml @nielsdos
/ext/mbstring @alexdowad @youkidearitai /ext/mbstring @alexdowad @youkidearitai
/ext/mysqli @bukka @kamil-tekiela /ext/mysqli @bukka @kamil-tekiela
@ -52,7 +52,6 @@
/ext/sockets @devnexen /ext/sockets @devnexen
/ext/spl @Girgias /ext/spl @Girgias
/ext/standard @bukka /ext/standard @bukka
/ext/uri @kocsismate
/ext/xml @nielsdos /ext/xml @nielsdos
/ext/xmlreader @nielsdos /ext/xmlreader @nielsdos
/ext/xmlwriter @nielsdos /ext/xmlwriter @nielsdos

View file

@ -22,23 +22,15 @@ body:
``` ```
validations: validations:
required: true required: true
- type: textarea - type: input
attributes: attributes:
label: PHP Version label: PHP Version
description: | description: "The used PHP version. Make sure it is [supported](https://www.php.net/supported-versions.php)."
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. placeholder: "PHP 8.0.12"
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
validations: validations:
required: true required: true
- type: input - type: input
attributes: attributes:
label: Operating System label: Operating System
description: "The used operating system, if relevant." description: "The used operating system, if relevant."
placeholder: "Ubuntu 24.04" placeholder: "Ubuntu 20.04"

View file

@ -3,3 +3,6 @@ contact_links:
- name: Documentation issue - name: Documentation issue
url: https://github.com/php/doc-en/issues url: https://github.com/php/doc-en/issues
about: Please report documentation issues on the doc-en repository. 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.

View file

@ -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

View file

@ -6,8 +6,6 @@ runs:
run: | run: |
set -x set -x
OPCACHE_TLS_TESTS_DEPS="gcc clang lld"
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
dpkg --add-architecture i386 dpkg --add-architecture i386
apt-get update -y | true apt-get update -y | true
@ -19,32 +17,37 @@ runs:
g++-multilib \ g++-multilib \
gcc-multilib \ gcc-multilib \
language-pack-de \ language-pack-de \
libaspell-dev:i386 \
libbz2-dev:i386 \ libbz2-dev:i386 \
libc6:i386 \ libc6:i386 \
libcurl4-openssl-dev:i386 \ libcurl4-openssl-dev:i386 \
libffi-dev:i386 \ libffi-dev:i386 \
libfreetype6-dev:i386 \ libfreetype6-dev:i386 \
libgmp-dev:i386 \ libgmp-dev:i386 \
libgssapi-krb5-2:i386 \
libicu-dev:i386 \ libicu-dev:i386 \
libjpeg-dev:i386 \ libjpeg-dev:i386 \
libkrb5-dev:i386 \
libonig-dev:i386 \ libonig-dev:i386 \
libpng-dev:i386 \ libpng-dev:i386 \
libpq-dev:i386 \ libpq-dev:i386 \
libpspell-dev:i386 \
libreadline-dev:i386 \ libreadline-dev:i386 \
libsasl2-dev:i386 \ libsasl2-dev:i386 \
libsodium-dev:i386 \ libsodium-dev:i386 \
libsqlite3-dev:i386 \ libsqlite3-dev:i386 \
libssl-dev:i386 \ libssl-dev:i386 \
libtidy-dev:i386 \
libwebp-dev:i386 \ libwebp-dev:i386 \
libxml2-dev:i386 \ libxml2-dev:i386 \
libxml2-dev:i386 \
libxpm-dev:i386 \ libxpm-dev:i386 \
libxslt1-dev:i386 \ libxslt1-dev:i386 \
firebird-dev:i386 \ libzip-dev:i386 \
locales \ locales \
make \ make \
pkg-config:i386 \ pkg-config:i386 \
re2c \ re2c \
unzip \ unzip \
wget \ wget \
zlib1g-dev:i386 \ zlib1g-dev:i386
$OPCACHE_TLS_TESTS_DEPS

View file

@ -1,8 +1,4 @@
name: apt name: apt
inputs:
asan:
default: false
required: false
runs: runs:
using: composite using: composite
steps: steps:
@ -10,8 +6,6 @@ runs:
run: | run: |
set -x set -x
OPCACHE_TLS_TESTS_DEPS="gcc clang lld"
export DEBIAN_FRONTEND=noninteractive export DEBIAN_FRONTEND=noninteractive
# Install sudo in Docker for consistent actions # Install sudo in Docker for consistent actions
@ -38,20 +32,22 @@ runs:
libicu-dev \ libicu-dev \
libtidy-dev \ libtidy-dev \
libenchant-2-dev \ libenchant-2-dev \
libaspell-dev \
libbz2-dev \ libbz2-dev \
libpspell-dev \
libsasl2-dev \ libsasl2-dev \
libxpm-dev \ libxpm-dev \
libzip-dev \ libzip-dev \
libsqlite3-dev \ libsqlite3-dev \
libsqlite3-mod-spatialite \
libwebp-dev \ libwebp-dev \
${{ inputs.asan == 'false' && 'libavif-dev' || '' }} \
libonig-dev \ libonig-dev \
libkrb5-dev \
libgssapi-krb5-2 \
libcurl4-openssl-dev \ libcurl4-openssl-dev \
libxml2-dev \ libxml2-dev \
libxslt1-dev \ libxslt1-dev \
libpq-dev \ libpq-dev \
libedit-dev \ libreadline-dev \
libldap2-dev \ libldap2-dev \
libsodium-dev \ libsodium-dev \
libargon2-dev \ libargon2-dev \
@ -65,6 +61,7 @@ runs:
unixodbc-dev \ unixodbc-dev \
llvm \ llvm \
clang \ clang \
libc-client-dev \
dovecot-core \ dovecot-core \
dovecot-pop3d \ dovecot-pop3d \
dovecot-imapd \ dovecot-imapd \
@ -76,5 +73,4 @@ runs:
libqdbm-dev \ libqdbm-dev \
libjpeg-dev \ libjpeg-dev \
libpng-dev \ libpng-dev \
libfreetype6-dev \ libfreetype6-dev
$OPCACHE_TLS_TESTS_DEPS

View file

@ -11,9 +11,6 @@ runs:
code=" keg.link\(verbose: verbose\?" code=" keg.link\(verbose: verbose\?"
sudo sed -Ei '' "s/$code.*/$code, overwrite: true\)/" "$formula_installer" 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 \ brew install \
bison \ bison \
re2c re2c
@ -22,6 +19,7 @@ runs:
enchant \ enchant \
libffi \ libffi \
intltool \ intltool \
icu4c \
libiconv \ libiconv \
t1lib \ t1lib \
libxml2 \ libxml2 \

View file

@ -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 }}

View file

@ -10,24 +10,26 @@ runs:
run: | run: |
set -x set -x
BREW_OPT="$(brew --prefix)"/opt BREW_OPT="$(brew --prefix)"/opt
export PATH="$BREW_OPT/bison/bin:$PATH" export PATH="/usr/local/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:/usr/local/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:/usr/local/opt/curl/lib/pkgconfig"
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$BREW_OPT/libffi/lib/pkgconfig" export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/krb5/lib/pkgconfig"
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$BREW_OPT/libxml2/lib/pkgconfig" export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/libffi/lib/pkgconfig"
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$BREW_OPT/libxslt/lib/pkgconfig" export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/libxml2/lib/pkgconfig"
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$BREW_OPT/zlib/lib/pkgconfig" export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/opt/libxslt/lib/pkgconfig"
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$BREW_OPT/icu4c/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" sed -i -e 's/Requires.private:.*//g' "$BREW_OPT/curl/lib/pkgconfig/libcurl.pc"
./buildconf --force ./buildconf --force
./configure \ ./configure \
CFLAGS="-Wno-strict-prototypes -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion" \
--enable-option-checking=fatal \ --enable-option-checking=fatal \
--prefix=/usr/local \ --prefix=/usr/local \
--enable-fpm \ --enable-fpm \
--with-pdo-mysql=mysqlnd \ --with-pdo-mysql=mysqlnd \
--with-mysqli=mysqlnd \ --with-mysqli=mysqlnd \
--with-pgsql="$BREW_OPT"/libpq \ --with-pgsql=/usr/local/opt/libpq \
--with-pdo-pgsql="$BREW_OPT"/libpq \ --with-pdo-pgsql=/usr/local/opt/libpq \
--with-pdo-sqlite \ --with-pdo-sqlite \
--without-pear \ --without-pear \
--enable-gd \ --enable-gd \
@ -40,24 +42,26 @@ runs:
--enable-soap \ --enable-soap \
--enable-xmlreader \ --enable-xmlreader \
--with-xsl \ --with-xsl \
--with-tidy="$BREW_OPT"/tidy-html5 \ --with-tidy=/usr/local/opt/tidy-html5 \
--with-libxml \ --with-libxml \
--enable-sysvsem \ --enable-sysvsem \
--enable-sysvshm \ --enable-sysvshm \
--enable-shmop \ --enable-shmop \
--enable-pcntl \ --enable-pcntl \
--with-readline="$BREW_OPT"/readline \ --with-readline=/usr/local/opt/readline \
--enable-mbstring \ --enable-mbstring \
--with-curl \ --with-curl \
--with-gettext="$BREW_OPT"/gettext \ --with-gettext=/usr/local/opt/gettext \
--enable-sockets \ --enable-sockets \
--with-bz2="$BREW_OPT"/bzip2 \ --with-bz2=/usr/local/opt/bzip2 \
--with-openssl \ --with-openssl \
--with-gmp="$BREW_OPT"/gmp \ --with-gmp=/usr/local/opt/gmp \
--with-iconv="$BREW_OPT"/libiconv \ --with-iconv=/usr/local/opt/libiconv \
--enable-bcmath \ --enable-bcmath \
--enable-calendar \ --enable-calendar \
--enable-ftp \ --enable-ftp \
--with-pspell=/usr/local/opt/aspell \
--with-kerberos \
--enable-sysvmsg \ --enable-sysvmsg \
--with-ffi \ --with-ffi \
--enable-zend-test \ --enable-zend-test \

View file

@ -10,7 +10,6 @@ runs:
run: | run: |
set -x set -x
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/lib/i386-linux-gnu/pkgconfig"
./buildconf --force ./buildconf --force
export CFLAGS="-m32 -msse2" export CFLAGS="-m32 -msse2"
export CXXFLAGS="-m32 -msse2" export CXXFLAGS="-m32 -msse2"
@ -27,7 +26,6 @@ runs:
--with-pgsql \ --with-pgsql \
--with-pdo-pgsql \ --with-pdo-pgsql \
--with-pdo-sqlite \ --with-pdo-sqlite \
--with-pdo-firebird \
--without-pear \ --without-pear \
--enable-gd \ --enable-gd \
--with-jpeg \ --with-jpeg \
@ -35,10 +33,13 @@ runs:
--with-freetype \ --with-freetype \
--with-xpm \ --with-xpm \
--enable-exif \ --enable-exif \
--with-zip \
--with-zlib \ --with-zlib \
--with-zlib-dir=/usr \
--enable-soap \ --enable-soap \
--enable-xmlreader \ --enable-xmlreader \
--with-xsl \ --with-xsl \
--with-tidy \
--enable-sysvsem \ --enable-sysvsem \
--enable-sysvshm \ --enable-sysvshm \
--enable-shmop \ --enable-shmop \
@ -54,6 +55,8 @@ runs:
--enable-bcmath \ --enable-bcmath \
--enable-calendar \ --enable-calendar \
--enable-ftp \ --enable-ftp \
--with-pspell=/usr \
--with-kerberos \
--enable-sysvmsg \ --enable-sysvmsg \
--with-ffi \ --with-ffi \
--enable-zend-test \ --enable-zend-test \

View file

@ -31,12 +31,12 @@ runs:
--enable-gd \ --enable-gd \
--with-jpeg \ --with-jpeg \
--with-webp \ --with-webp \
${{ inputs.asan == 'false' && '--with-avif' || '' }} \
--with-freetype \ --with-freetype \
--with-xpm \ --with-xpm \
--enable-exif \ --enable-exif \
--with-zip \ --with-zip \
--with-zlib \ --with-zlib \
--with-zlib-dir=/usr \
--enable-soap \ --enable-soap \
--enable-xmlreader \ --enable-xmlreader \
--with-xsl \ --with-xsl \
@ -45,7 +45,7 @@ runs:
--enable-sysvshm \ --enable-sysvshm \
--enable-shmop \ --enable-shmop \
--enable-pcntl \ --enable-pcntl \
--without-readline --with-libedit \ --with-readline \
--enable-mbstring \ --enable-mbstring \
--with-curl \ --with-curl \
--with-gettext \ --with-gettext \
@ -56,7 +56,9 @@ runs:
--enable-bcmath \ --enable-bcmath \
--enable-calendar \ --enable-calendar \
--enable-ftp \ --enable-ftp \
--with-pspell=/usr \
${{ inputs.skipSlow == 'false' && '--with-enchant=/usr' || '' }} \ ${{ inputs.skipSlow == 'false' && '--with-enchant=/usr' || '' }} \
--with-kerberos \
--enable-sysvmsg \ --enable-sysvmsg \
--with-ffi \ --with-ffi \
--enable-zend-test \ --enable-zend-test \
@ -75,7 +77,11 @@ runs:
--with-qdbm \ --with-qdbm \
${{ inputs.skipSlow == 'false' && '--with-snmp' || '' }} \ ${{ inputs.skipSlow == 'false' && '--with-snmp' || '' }} \
${{ inputs.skipSlow == 'false' && '--with-unixODBC' || '' }} \ ${{ inputs.skipSlow == 'false' && '--with-unixODBC' || '' }} \
${{ inputs.skipSlow == 'false' && '--with-imap' || '' }} \
${{ inputs.skipSlow == 'false' && '--with-imap-ssl' || '' }} \
${{ inputs.skipSlow == 'false' && '--with-pdo-odbc=unixODBC,/usr' || '' }} \ ${{ 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-path=/etc \
--with-config-file-scan-dir=/etc/php.d \ --with-config-file-scan-dir=/etc/php.d \
${{ inputs.skipSlow == 'false' && '--with-pdo-firebird' || '' }} \ ${{ inputs.skipSlow == 'false' && '--with-pdo-firebird' || '' }} \

View file

@ -1,7 +0,0 @@
name: Extra tests
runs:
using: composite
steps:
- shell: sh
run: |
sapi/cli/php run-extra-tests.php

View file

@ -3,16 +3,13 @@ inputs:
configurationParameters: configurationParameters:
default: '' default: ''
required: false required: false
runExtraTests:
default: false
required: false
runs: runs:
using: composite using: composite
steps: steps:
- name: FreeBSD - name: FreeBSD
uses: vmactions/freebsd-vm@v1 uses: vmactions/freebsd-vm@v1
with: with:
release: '13.5' release: '13.3'
usesh: true usesh: true
copyback: false copyback: false
# Temporarily disable sqlite, as FreeBSD ships it with disabled double quotes. We'll need to fix our tests. # Temporarily disable sqlite, as FreeBSD ships it with disabled double quotes. We'll need to fix our tests.
@ -20,8 +17,6 @@ runs:
prepare: | prepare: |
cd $GITHUB_WORKSPACE cd $GITHUB_WORKSPACE
OPCACHE_TLS_TESTS_DEPS="gcc"
kldload accf_http kldload accf_http
pkg install -y \ pkg install -y \
autoconf \ autoconf \
@ -46,11 +41,9 @@ runs:
webp \ webp \
libavif \ libavif \
`#sqlite3` \ `#sqlite3` \
curl \ curl
$OPCACHE_TLS_TESTS_DEPS
./buildconf -f ./buildconf -f
CC=clang CXX=clang++ \
./configure \ ./configure \
--prefix=/usr/local \ --prefix=/usr/local \
--enable-debug \ --enable-debug \
@ -89,7 +82,6 @@ runs:
--enable-intl \ --enable-intl \
--with-mhash \ --with-mhash \
--with-sodium \ --with-sodium \
--enable-werror \
--with-config-file-path=/etc \ --with-config-file-path=/etc \
--with-config-file-scan-dir=/etc/php.d \ --with-config-file-scan-dir=/etc/php.d \
${{ inputs.configurationParameters }} ${{ inputs.configurationParameters }}
@ -113,8 +105,5 @@ runs:
--offline \ --offline \
--show-diff \ --show-diff \
--show-slow 1000 \ --show-slow 1000 \
--set-timeout 120 --set-timeout 120 \
-d zend_extension=opcache.so
if test "${{ inputs.runExtraTests }}" = "true"; then
sapi/cli/php run-extra-tests.php
fi

View file

@ -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
View 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

View file

@ -19,3 +19,9 @@ runs:
sudo cp ext/snmp/tests/snmpd.conf /etc/snmp sudo cp ext/snmp/tests/snmpd.conf /etc/snmp
sudo cp ext/snmp/tests/bigtest /etc/snmp sudo cp ext/snmp/tests/bigtest /etc/snmp
sudo service snmpd restart 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

View file

@ -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

View file

@ -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_DSN="dblib:host=127.0.0.1;dbname=master;version=7.0"
export PDO_DBLIB_TEST_USER="pdo_test" export PDO_DBLIB_TEST_USER="pdo_test"
export PDO_DBLIB_TEST_PASS="password" 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" export PGSQL_TEST_CONNSTR="host=localhost dbname=test port=5432 user=postgres password=postgres"
if [[ -z "$PDO_PGSQL_TEST_DSN" ]]; then if [[ -z "$PDO_PGSQL_TEST_DSN" ]]; then
export PDO_PGSQL_TEST_DSN="pgsql:host=localhost port=5432 dbname=test user=postgres password=postgres" export PDO_PGSQL_TEST_DSN="pgsql:host=localhost port=5432 dbname=test user=postgres password=postgres"
fi 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_USER="odbc_test"
export ODBC_TEST_PASS="password" 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" 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 export STACK_LIMIT_DEFAULTS_CHECK=1
sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \ sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \
-d opcache.jit=${{ inputs.jitType }} \ -d opcache.jit=${{ inputs.jitType }} \
-d opcache.protect_memory=1 \ -d opcache.jit_buffer_size=16M \
-d opcache.jit_buffer_size=64M \
${{ inputs.idleCpu == 'true' && '-j$(($(/usr/bin/nproc) - 1))' || '-j$(/usr/bin/nproc)' }} \ ${{ inputs.idleCpu == 'true' && '-j$(($(/usr/bin/nproc) - 1))' || '-j$(/usr/bin/nproc)' }} \
-g FAIL,BORK,LEAK,XLEAK \ -g FAIL,BORK,LEAK,XLEAK \
--no-progress \ --no-progress \

View file

@ -17,8 +17,7 @@ runs:
export STACK_LIMIT_DEFAULTS_CHECK=1 export STACK_LIMIT_DEFAULTS_CHECK=1
sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \ sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \
-d opcache.jit=${{ inputs.jitType }} \ -d opcache.jit=${{ inputs.jitType }} \
-d opcache.protect_memory=1 \ -d opcache.jit_buffer_size=16M \
-d opcache.jit_buffer_size=64M \
-j$(($(sysctl -n hw.ncpu) - 1)) \ -j$(($(sysctl -n hw.ncpu) - 1)) \
-g FAIL,BORK,LEAK,XLEAK \ -g FAIL,BORK,LEAK,XLEAK \
--no-progress \ --no-progress \

View file

@ -4,13 +4,13 @@ runs:
steps: steps:
- shell: bash - shell: bash
run: | run: |
set -ex set -x
[[ "$OSTYPE" == "darwin"* ]] && export PATH="$(brew --prefix)/opt/bison/bin:$PATH" [[ "$OSTYPE" == "darwin"* ]] && export PATH="/usr/local/opt/bison/bin:$PATH"
scripts/dev/credits scripts/dev/credits
scripts/dev/genfiles scripts/dev/genfiles
scripts/gdb/debug_gdb_scripts_gen.php
Zend/zend_vm_gen.php Zend/zend_vm_gen.php
ext/tokenizer/tokenizer_data_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. # 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 git add . -N && git diff -a --exit-code

517
.github/labeler.yml vendored
View file

@ -1,501 +1,326 @@
"Category: Engine": "Category: Engine":
- changed-files: - Zend/*
- any-glob-to-any-file:
- Zend/*
"Category: Optimizer": "Category: Optimizer":
- changed-files: - Zend/Optimizer/**/*
- any-glob-to-any-file:
- Zend/Optimizer/**/*
"Category: Build System": "Category: Build System":
- changed-files: - '**/*.m4'
- any-glob-to-any-file: - '**/*.w32'
- '**/*.m4' - build/**/*
- '**/*.w32' - buildconf
- build/**/* - buildconf.bat
- buildconf - configure.ac
- buildconf.bat - scripts/**/*
- configure.ac - win32/build/**/*
- scripts/**/*
- win32/build/**/*
"Extension: bcmath": "Extension: bcmath":
- changed-files: - ext/bcmath/**/*
- any-glob-to-any-file:
- ext/bcmath/**/*
"Extension: bz2": "Extension: bz2":
- changed-files: - ext/bz2/**/*
- any-glob-to-any-file:
- ext/bz2/**/*
"Extension: calendar": "Extension: calendar":
- changed-files: - ext/calendar/**/*
- any-glob-to-any-file:
- ext/calendar/**/*
"Extension: com_dotnet": "Extension: com_dotnet":
- changed-files: - ext/com_dotnet/**/*
- any-glob-to-any-file:
- ext/com_dotnet/**/*
"Extension: ctype": "Extension: ctype":
- changed-files: - ext/ctype/**/*
- any-glob-to-any-file:
- ext/ctype/**/*
"Extension: curl": "Extension: curl":
- changed-files: - ext/curl/**/*
- any-glob-to-any-file:
- ext/curl/**/*
"Extension: date": "Extension: date":
- changed-files: - ext/date/**/*
- any-glob-to-any-file:
- ext/date/**/*
"Extension: dba": "Extension: dba":
- changed-files: - ext/dba/**/*
- any-glob-to-any-file:
- ext/dba/**/*
"Extension: dom": "Extension: dom":
- changed-files: - ext/dom/**/*
- any-glob-to-any-file:
- ext/dom/**/*
"Extension: enchant": "Extension: enchant":
- changed-files: - ext/enchant/**/*
- any-glob-to-any-file:
- ext/enchant/**/*
"Extension: exif": "Extension: exif":
- changed-files: - ext/exif/**/*
- any-glob-to-any-file:
- ext/exif/**/*
"Extension: ffi": "Extension: ffi":
- changed-files: - ext/ffi/**/*
- any-glob-to-any-file:
- ext/ffi/**/*
"Extension: fileinfo": "Extension: fileinfo":
- changed-files: - ext/fileinfo/**/*
- any-glob-to-any-file:
- ext/fileinfo/**/*
"Extension: filter": "Extension: filter":
- changed-files: - ext/filter/**/*
- any-glob-to-any-file:
- ext/filter/**/*
"Extension: ftp": "Extension: ftp":
- changed-files: - ext/ftp/**/*
- any-glob-to-any-file:
- ext/ftp/**/*
"Extension: gd": "Extension: gd":
- changed-files: - ext/gd/**/*
- any-glob-to-any-file:
- ext/gd/**/*
"Extension: gettext": "Extension: gettext":
- changed-files: - ext/gettext/**/*
- any-glob-to-any-file:
- ext/gettext/**/*
"Extension: gmp": "Extension: gmp":
- changed-files: - ext/gmp/**/*
- any-glob-to-any-file:
- ext/gmp/**/*
"Extension: hash": "Extension: hash":
- changed-files: - ext/hash/**/*
- any-glob-to-any-file:
- ext/hash/**/*
"Extension: iconv": "Extension: iconv":
- changed-files: - ext/iconv/**/*
- any-glob-to-any-file:
- ext/iconv/**/* "Extension: imap":
- ext/imap/**/*
"Extension: intl": "Extension: intl":
- changed-files: - ext/intl/**/*
- any-glob-to-any-file:
- ext/intl/**/*
"Extension: json": "Extension: json":
- changed-files: - ext/json/**/*
- any-glob-to-any-file:
- ext/json/**/*
"Extension: ldap": "Extension: ldap":
- changed-files: - ext/ldap/**/*
- any-glob-to-any-file:
- ext/ldap/**/*
"Extension: libxml": "Extension: libxml":
- changed-files: - ext/libxml/**/*
- any-glob-to-any-file:
- ext/libxml/**/*
"Extension: mbstring": "Extension: mbstring":
- changed-files: - ext/mbstring/**/*
- any-glob-to-any-file:
- ext/mbstring/**/*
"Extension: mysqli": "Extension: mysqli":
- changed-files: - ext/mysqli/**/*
- any-glob-to-any-file:
- ext/mysqli/**/*
"Extension: mysqlnd": "Extension: mysqlnd":
- changed-files: - ext/mysqlnd/**/*
- any-glob-to-any-file:
- ext/mysqlnd/**/* "Extension: oci8":
- ext/oci8/**/*
"Extension: odbc": "Extension: odbc":
- changed-files: - ext/odbc/**/*
- any-glob-to-any-file:
- ext/odbc/**/*
"Extension: opcache": "Extension: opcache":
- changed-files: - ext/opcache/**/*
- any-glob-to-any-file:
- ext/opcache/**/*
"Extension: openssl": "Extension: openssl":
- changed-files: - ext/openssl/**/*
- any-glob-to-any-file:
- ext/openssl/**/*
"Extension: pcntl": "Extension: pcntl":
- changed-files: - ext/pcntl/**/*
- any-glob-to-any-file:
- ext/pcntl/**/*
"Extension: pcre": "Extension: pcre":
- changed-files: - ext/pcre/**/*
- any-glob-to-any-file:
- ext/pcre/**/*
"Extension: pdo (core)": "Extension: pdo (core)":
- changed-files: - ext/pdo/**/*
- any-glob-to-any-file:
- ext/pdo/**/*
"Extension: pdo_dblib": "Extension: pdo_dblib":
- changed-files: - ext/pdo_dblib/**/*
- any-glob-to-any-file:
- ext/pdo_dblib/**/*
"Extension: pdo_firebird": "Extension: pdo_firebird":
- changed-files: - ext/pdo_firebird/**/*
- any-glob-to-any-file:
- ext/pdo_firebird/**/*
"Extension: pdo_mysql": "Extension: pdo_mysql":
- changed-files: - ext/pdo_mysql/**/*
- any-glob-to-any-file:
- ext/pdo_mysql/**/* "Extension: pdo_oci":
- ext/pdo_oci/**/*
"Extension: pdo_odbc": "Extension: pdo_odbc":
- changed-files: - ext/pdo_odbc/**/*
- any-glob-to-any-file:
- ext/pdo_odbc/**/*
"Extension: pdo_pgsql": "Extension: pdo_pgsql":
- changed-files: - ext/pdo_pgsql/**/*
- any-glob-to-any-file:
- ext/pdo_pgsql/**/*
"Extension: pdo_sqlite": "Extension: pdo_sqlite":
- changed-files: - ext/pdo_sqlite/**/*
- any-glob-to-any-file:
- ext/pdo_sqlite/**/*
"Extension: pgsql": "Extension: pgsql":
- changed-files: - ext/pgsql/**/*
- any-glob-to-any-file:
- ext/pgsql/**/*
"Extension: phar": "Extension: phar":
- changed-files: - ext/phar/**/*
- any-glob-to-any-file:
- ext/phar/**/*
"Extension: posix": "Extension: posix":
- changed-files: - ext/posix/**/*
- any-glob-to-any-file:
- ext/posix/**/* "Extension: pspell":
- ext/pspell/**/*
"Extension: random": "Extension: random":
- changed-files: - ext/random/**/*
- any-glob-to-any-file:
- ext/random/**/*
"Extension: readline": "Extension: readline":
- changed-files: - ext/readline/**/*
- any-glob-to-any-file:
- ext/readline/**/*
"Extension: reflection": "Extension: reflection":
- changed-files: - ext/reflection/**/*
- any-glob-to-any-file:
- ext/reflection/**/*
"Extension: session": "Extension: session":
- changed-files: - ext/session/**/*
- any-glob-to-any-file:
- ext/session/**/*
"Extension: shmop": "Extension: shmop":
- changed-files: - ext/shmop/**/*
- any-glob-to-any-file:
- ext/shmop/**/*
"Extension: simplexml": "Extension: simplexml":
- changed-files: - ext/simplexml/**/*
- any-glob-to-any-file:
- ext/simplexml/**/*
"Extension: snmp": "Extension: snmp":
- changed-files: - ext/snmp/**/*
- any-glob-to-any-file:
- ext/snmp/**/*
"Extension: soap": "Extension: soap":
- changed-files: - ext/soap/**/*
- any-glob-to-any-file:
- ext/soap/**/*
"Extension: sockets": "Extension: sockets":
- changed-files: - ext/sockets/**/*
- any-glob-to-any-file:
- ext/sockets/**/*
"Extension: sodium": "Extension: sodium":
- changed-files: - ext/sodium/**/*
- any-glob-to-any-file:
- ext/sodium/**/*
"Extension: spl": "Extension: spl":
- changed-files: - ext/spl/**/*
- any-glob-to-any-file:
- ext/spl/**/*
"Extension: sqlite3": "Extension: sqlite3":
- changed-files: - ext/sqlite3/**/*
- any-glob-to-any-file:
- ext/sqlite3/**/*
"Extension: standard": "Extension: standard":
- changed-files: - ext/standard/**/*
- any-glob-to-any-file:
- ext/standard/**/*
"Extension: sysvmsg": "Extension: sysvmsg":
- changed-files: - ext/sysvmsg/**/*
- any-glob-to-any-file:
- ext/sysvmsg/**/*
"Extension: sysvsem": "Extension: sysvsem":
- changed-files: - ext/sysvsem/**/*
- any-glob-to-any-file:
- ext/sysvsem/**/*
"Extension: sysvshm": "Extension: sysvshm":
- changed-files: - ext/sysvshm/**/*
- any-glob-to-any-file:
- ext/sysvshm/**/*
"Extension: tidy": "Extension: tidy":
- changed-files: - ext/tidy/**/*
- any-glob-to-any-file:
- ext/tidy/**/*
"Extension: tokenizer": "Extension: tokenizer":
- changed-files: - ext/tokenizer/**/*
- any-glob-to-any-file:
- ext/tokenizer/**/*
"Extension: uri":
- changed-files:
- any-glob-to-any-file:
- ext/uri/**/*
"Extension: xml": "Extension: xml":
- changed-files: - ext/xml/**/*
- any-glob-to-any-file:
- ext/xml/**/*
"Extension: xmlreader": "Extension: xmlreader":
- changed-files: - ext/xmlreader/**/*
- any-glob-to-any-file:
- ext/xmlreader/**/*
"Extension: xmlwriter": "Extension: xmlwriter":
- changed-files: - ext/xmlwriter/**/*
- any-glob-to-any-file:
- ext/xmlwriter/**/*
"Extension: xsl": "Extension: xsl":
- changed-files: - ext/xsl/**/*
- any-glob-to-any-file:
- ext/xsl/**/*
"Extension: zend_test": "Extension: zend_test":
- changed-files: - ext/zend_test/**/*
- any-glob-to-any-file:
- ext/zend_test/**/*
"Extension: zip": "Extension: zip":
- changed-files: - ext/zip/**/*
- any-glob-to-any-file:
- ext/zip/**/*
"Extension: zlib": "Extension: zlib":
- changed-files: - ext/zlib/**/*
- any-glob-to-any-file:
- ext/zlib/**/*
"SAPI: apache2handler": "SAPI: apache2handler":
- changed-files: - sapi/apache2handler/**/*
- any-glob-to-any-file:
- sapi/apache2handler/**/*
"SAPI: cgi": "SAPI: cgi":
- changed-files: - sapi/cgi/**/*
- any-glob-to-any-file:
- sapi/cgi/**/*
"SAPI: cli": "SAPI: cli":
- changed-files: - sapi/cli/**/*
- any-glob-to-any-file:
- sapi/cli/**/*
"SAPI: fpm": "SAPI: fpm":
- changed-files: - sapi/fpm/**/*
- any-glob-to-any-file:
- sapi/fpm/**/*
"SAPI: fuzzer": "SAPI: fuzzer":
- changed-files: - sapi/fuzzer/**/*
- any-glob-to-any-file:
- sapi/fuzzer/**/*
"SAPI: litespeed": "SAPI: litespeed":
- changed-files: - sapi/litespeed/**/*
- any-glob-to-any-file:
- sapi/litespeed/**/*
"SAPI: phpdbg": "SAPI: phpdbg":
- changed-files: - sapi/phpdbg/**/*
- any-glob-to-any-file:
- sapi/phpdbg/**/*
"ABI break": "ABI break":
- changed-files: - 'TSRM/*.h'
- any-glob-to-any-file: - 'Zend/*.h'
- 'TSRM/*.h' - 'Zend/Optimizer/zend_call_graph.h'
- 'Zend/*.h' - 'Zend/Optimizer/zend_cfg.h'
- 'Zend/Optimizer/zend_call_graph.h' - 'Zend/Optimizer/zend_dump.h'
- 'Zend/Optimizer/zend_cfg.h' - 'Zend/Optimizer/zend_func_info.h'
- 'Zend/Optimizer/zend_dfg.h' - 'Zend/Optimizer/zend_inference.h'
- 'Zend/Optimizer/zend_dump.h' - 'Zend/Optimizer/zend_optimizer.h'
- 'Zend/Optimizer/zend_func_info.h' - 'Zend/Optimizer/zend_ssa.h'
- 'Zend/Optimizer/zend_inference.h' - 'ext/date/lib/timelib.h'
- 'Zend/Optimizer/zend_optimizer.h' - 'ext/date/lib/timelib_config.h'
- 'Zend/Optimizer/zend_ssa.h' - 'ext/date/php_date.h'
- 'Zend/Optimizer/zend_worklist.h' - 'ext/filter/php_filter.h'
- 'ext/curl/php_curl.h' - 'ext/hash/php_hash.h'
- 'ext/date/lib/timelib.h' - 'ext/hash/php_hash_adler32.h'
- 'ext/date/lib/timelib_config.h' - 'ext/hash/php_hash_crc32.h'
- 'ext/date/php_date.h' - 'ext/hash/php_hash_gost.h'
- 'ext/dom/dom_ce.h' - 'ext/hash/php_hash_haval.h'
- 'ext/dom/namespace_compat.h' - 'ext/hash/php_hash_md.h'
- 'ext/dom/xml_common.h' - 'ext/hash/php_hash_murmur.h'
- 'ext/dom/xpath_callbacks.h' - 'ext/hash/php_hash_ripemd.h'
- 'ext/filter/php_filter.h' - 'ext/hash/php_hash_sha.h'
- 'ext/gd/libgd/*.h' - 'ext/hash/php_hash_sha3.h'
- 'ext/gd/php_gd.h' - 'ext/hash/php_hash_snefru.h'
- 'ext/gmp/php_gmp_int.h' - 'ext/hash/php_hash_tiger.h'
- 'ext/hash/php_hash.h' - 'ext/hash/php_hash_whirlpool.h'
- 'ext/hash/php_hash_adler32.h' - 'ext/hash/php_hash_xxhash.h'
- 'ext/hash/php_hash_crc32.h' - 'ext/json/php_json.h'
- 'ext/hash/php_hash_fnv.h' - 'ext/json/php_json_parser.h'
- 'ext/hash/php_hash_gost.h' - 'ext/json/php_json_scanner.h'
- 'ext/hash/php_hash_haval.h' - 'ext/mbstring/libmbfl/config.h'
- 'ext/hash/php_hash_joaat.h' - 'ext/mbstring/libmbfl/mbfl/eaw_table.h'
- 'ext/hash/php_hash_md.h' - 'ext/mbstring/libmbfl/mbfl/mbfilter.h'
- 'ext/hash/php_hash_murmur.h' - 'ext/mbstring/libmbfl/mbfl/mbfilter_8bit.h'
- 'ext/hash/php_hash_ripemd.h' - 'ext/mbstring/libmbfl/mbfl/mbfilter_pass.h'
- 'ext/hash/php_hash_sha.h' - 'ext/mbstring/libmbfl/mbfl/mbfilter_wchar.h'
- 'ext/hash/php_hash_sha3.h' - 'ext/mbstring/libmbfl/mbfl/mbfl_consts.h'
- 'ext/hash/php_hash_snefru.h' - 'ext/mbstring/libmbfl/mbfl/mbfl_convert.h'
- 'ext/hash/php_hash_tiger.h' - 'ext/mbstring/libmbfl/mbfl/mbfl_defs.h'
- 'ext/hash/php_hash_whirlpool.h' - 'ext/mbstring/libmbfl/mbfl/mbfl_encoding.h'
- 'ext/hash/php_hash_xxhash.h' - 'ext/mbstring/libmbfl/mbfl/mbfl_filter_output.h'
- 'ext/hash/xxhash/xxhash.h' - 'ext/mbstring/libmbfl/mbfl/mbfl_language.h'
- 'ext/iconv/php_iconv.h' - 'ext/mbstring/libmbfl/mbfl/mbfl_memory_device.h'
- 'ext/json/php_json.h' - 'ext/mbstring/libmbfl/mbfl/mbfl_string.h'
- 'ext/json/php_json_parser.h' - 'ext/mbstring/mbstring.h'
- 'ext/json/php_json_scanner.h' - 'ext/mysqli/php_mysqli_structs.h'
- 'ext/libxml/php_libxml.h' - 'ext/mysqlnd/*.h'
- 'ext/mbstring/libmbfl/config.h' - 'ext/pcre/pcre2lib/*.h'
- 'ext/mbstring/libmbfl/mbfl/eaw_table.h' - 'ext/pcre/php_pcre.h'
- 'ext/mbstring/libmbfl/mbfl/mbfilter.h' - 'ext/pdo/php_pdo.h'
- 'ext/mbstring/libmbfl/mbfl/mbfilter_8bit.h' - 'ext/pdo/php_pdo_driver.h'
- 'ext/mbstring/libmbfl/mbfl/mbfilter_pass.h' - 'ext/pdo/php_pdo_error.h'
- 'ext/mbstring/libmbfl/mbfl/mbfilter_wchar.h' - 'ext/random/php_random.h'
- 'ext/mbstring/libmbfl/mbfl/mbfl_consts.h' - 'ext/session/mod_files.h'
- 'ext/mbstring/libmbfl/mbfl/mbfl_convert.h' - 'ext/session/mod_mm.h'
- 'ext/mbstring/libmbfl/mbfl/mbfl_defs.h' - 'ext/session/mod_user.h'
- 'ext/mbstring/libmbfl/mbfl/mbfl_encoding.h' - 'ext/session/php_session.h'
- 'ext/mbstring/libmbfl/mbfl/mbfl_filter_output.h' - 'ext/sockets/php_sockets.h'
- 'ext/mbstring/libmbfl/mbfl/mbfl_language.h' - 'ext/sockets/windows_common.h'
- 'ext/mbstring/libmbfl/mbfl/mbfl_memory_device.h' - 'ext/spl/php_spl.h'
- 'ext/mbstring/libmbfl/mbfl/mbfl_string.h' - 'ext/spl/spl_array.h'
- 'ext/mbstring/mbstring.h' - 'ext/spl/spl_directory.h'
- 'ext/mbstring/php_mbregex.h' - 'ext/spl/spl_dllist.h'
- 'ext/mbstring/php_onig_compat.h' - 'ext/spl/spl_engine.h'
- 'ext/mysqli/mysqli_mysqlnd.h' - 'ext/spl/spl_exceptions.h'
- 'ext/mysqli/php_mysqli_structs.h' - 'ext/spl/spl_fixedarray.h'
- 'ext/mysqlnd/*.h' - 'ext/spl/spl_functions.h'
- 'ext/pcre/pcre2lib/*.h' - 'ext/spl/spl_heap.h'
- 'ext/pcre/php_pcre.h' - 'ext/spl/spl_iterators.h'
- 'ext/pdo/pdo_sql_parser.h' - 'ext/spl/spl_observer.h'
- 'ext/pdo/php_pdo.h' - 'ext/standard/*.h'
- 'ext/pdo/php_pdo_driver.h' - 'main/*.h'
- 'ext/pdo/php_pdo_error.h' - 'main/streams/*.h'
- 'ext/random/php_random.h' - 'sapi/embed/php_embed.h'
- 'ext/random/php_random_csprng.h' - 'win32/*.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_exceptions.h'
- 'ext/spl/spl_fixedarray.h'
- 'ext/spl/spl_functions.h'
- 'ext/spl/spl_heap.h'
- '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'

View file

@ -1,4 +1,3 @@
leak:acommon::DictInfoList::elements leak:acommon::DictInfoList::elements
leak:timer_create leak:timer_create
leak:netsnmp_init_mib_internals leak:netsnmp_init_mib_internals
leak:isc_attach_database

View file

@ -72,9 +72,6 @@ olcTLSCertificateKeyFile: /etc/ldap/ssl/server.key
add: olcTLSVerifyClient add: olcTLSVerifyClient
olcTLSVerifyClient: never olcTLSVerifyClient: never
- -
add: olcTLSProtocolMin
olcTLSProtocolMin: 3.3
-
add: olcAuthzRegexp add: olcAuthzRegexp
olcAuthzRegexp: uid=usera,cn=digest-md5,cn=auth cn=usera,dc=my-domain,dc=com olcAuthzRegexp: uid=usera,cn=digest-md5,cn=auth cn=usera,dc=my-domain,dc=com
- -

View file

@ -1,3 +1,5 @@
@echo off
if /i "%GITHUB_ACTIONS%" neq "True" ( if /i "%GITHUB_ACTIONS%" neq "True" (
echo for CI only echo for CI only
exit /b 3 exit /b 3

View file

@ -25,17 +25,18 @@ if %errorlevel% neq 0 exit /b 3
if "%THREAD_SAFE%" equ "0" set ADD_CONF=%ADD_CONF% --disable-zts 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 "%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 Some undefined behavior is reported on 32-bit, this should be fixed
rem C4146: unary minus operator applied to unsigned type if "%PLATFORM%" == "x86" (
rem C4244: type conversion, possible loss of data set CFLAGS=/W1
rem C4267: 'size_t' type conversion, possible loss of data ) else (
set CFLAGS=/W3 /WX /wd4018 /wd4146 /wd4244 /wd4267 set CFLAGS=/W1 /WX
)
cmd /c configure.bat ^ cmd /c configure.bat ^
--enable-snapshot-build ^ --enable-snapshot-build ^
--disable-debug-pack ^ --disable-debug-pack ^
--enable-com-dotnet=shared ^
--without-analyzer ^ --without-analyzer ^
--enable-object-out-dir=%PHP_BUILD_OBJ_DIR% ^ --enable-object-out-dir=%PHP_BUILD_OBJ_DIR% ^
--with-php-build=%DEPS_DIR% ^ --with-php-build=%DEPS_DIR% ^
@ -45,7 +46,5 @@ if %errorlevel% neq 0 exit /b 3
nmake /NOLOGO nmake /NOLOGO
if %errorlevel% neq 0 exit /b 3 if %errorlevel% neq 0 exit /b 3
nmake /NOLOGO comtest.dll
if %errorlevel% neq 0 exit /b 3
exit /b 0 exit /b 0

View file

@ -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_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 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 set BRANCH=master
) )

View file

@ -1,3 +1,5 @@
@echo off
if /i "%GITHUB_ACTIONS%" neq "True" ( if /i "%GITHUB_ACTIONS%" neq "True" (
echo for CI only echo for CI only
exit /b 3 exit /b 3

View file

@ -1,3 +1,5 @@
@echo off
if /i "%GITHUB_ACTIONS%" neq "True" ( if /i "%GITHUB_ACTIONS%" neq "True" (
echo for CI only echo for CI only
exit /b 3 exit /b 3
@ -51,22 +53,19 @@ set PDOTEST_DSN=odbc:%ODBC_TEST_DSN%
rem setup Firebird related exts rem setup Firebird related exts
if "%PLATFORM%" == "x64" ( 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 ( ) 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% curl -sLo Firebird.zip %PHP_FIREBIRD_DOWNLOAD_URL%
7z x -oC:\Firebird Firebird.zip 7z x -oC:\Firebird Firebird.zip
set PDO_FIREBIRD_TEST_DATABASE=C:\test.fdb 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_USER=SYSDBA
set PDO_FIREBIRD_TEST_PASS=phpfi 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 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\instsvc.exe install -n TestInstance
C:\Firebird\isql -q -i C:\Firebird\setup.sql 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 C:\Firebird\instsvc.exe start -n TestInstance
if %errorlevel% neq 0 exit /b 3 if %errorlevel% neq 0 exit /b 3
path C:\Firebird;%PATH% path C:\Firebird;%PATH%
@ -91,7 +90,9 @@ set OPENSSL_CONF=
rem set SSLEAY_CONF= rem set SSLEAY_CONF=
rem prepare for OPcache 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 rem prepare for enchant
mkdir %~d0\usr\local\lib\enchant-2 mkdir %~d0\usr\local\lib\enchant-2
@ -109,7 +110,6 @@ popd
rem prepare for snmp rem prepare for snmp
set MIBDIRS=%DEPS_DIR%\share\mibs 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 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 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 curl -sLo hMailServer.exe https://www.hmailserver.com/download_file/?downloadid=271
hMailServer.exe /verysilent hMailServer.exe /verysilent
cd %APPVEYOR_BUILD_FOLDER% cd %APPVEYOR_BUILD_FOLDER%
%PHP_BUILD_DIR%\php.exe -dextension_dir=%PHP_BUILD_DIR% -dextension=com_dotnet .github\setup_hmailserver.php %PHP_BUILD_DIR%\php.exe -dextension_dir=%PHP_BUILD_DIR% -dextension=com_dotnet appveyor\setup_hmailserver.php
rem prepare for com_dotnet
nmake register_comtest
mkdir %PHP_BUILD_DIR%\test_file_cache mkdir %PHP_BUILD_DIR%\test_file_cache
rem generate php.ini rem generate php.ini
echo extension_dir=%PHP_BUILD_DIR% > %PHP_BUILD_DIR%\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.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 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_openssl.dll >> %PHP_BUILD_DIR%\php.ini
echo extension=php_sockets.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 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 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 set TEST_PHPDBG_EXECUTABLE=%PHP_BUILD_DIR%\phpdbg.exe
copy /-y %DEPS_DIR%\bin\*.dll %PHP_BUILD_DIR%\* copy /-y %DEPS_DIR%\bin\*.dll %PHP_BUILD_DIR%\*
if "%ASAN%" equ "1" set ASAN_OPTS=--asan
mkdir c:\tests_tmp 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% set EXIT_CODE=%errorlevel%
nmake unregister_comtest
taskkill /f /im snmpd.exe 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% exit /b %EXIT_CODE%

View file

@ -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();
}

View file

@ -9,7 +9,7 @@ permissions:
jobs: jobs:
build: build:
if: github.repository == 'php/php-src' if: github.repository_owner == 'php'
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
issues: write issues: write

View file

@ -9,13 +9,13 @@ permissions:
jobs: jobs:
stale: stale:
if: github.repository == 'php/php-src' if: github.repository_owner == 'php'
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
issues: write issues: write
pull-requests: write pull-requests: write
steps: steps:
- uses: actions/stale@v9 - uses: actions/stale@v6
with: with:
days-before-close: 14 days-before-close: 14
days-before-stale: 90 days-before-stale: 90

View file

@ -9,13 +9,13 @@ permissions:
jobs: jobs:
stale: stale:
if: github.repository == 'php/php-src' if: github.repository_owner == 'php'
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
issues: write issues: write
pull-requests: write pull-requests: write
steps: steps:
- uses: actions/stale@v9 - uses: actions/stale@v6
with: with:
days-before-close: 7 days-before-close: 7
days-before-stale: 60 days-before-stale: 60

View file

@ -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

View file

@ -12,6 +12,6 @@ jobs:
pull-requests: write pull-requests: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/labeler@v5 - uses: actions/labeler@v4
with: with:
repo-token: "${{ secrets.GITHUB_TOKEN }}" repo-token: "${{ secrets.GITHUB_TOKEN }}"

View file

@ -54,7 +54,7 @@ jobs:
runs-on: [self-hosted, gentoo, ppc64] runs-on: [self-hosted, gentoo, ppc64]
steps: steps:
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: System info - name: System info
@ -85,8 +85,6 @@ jobs:
with: with:
runTestsParameters: >- runTestsParameters: >-
--asan -x --asan -x
- name: Extra tests
uses: ./.github/actions/extra-tests
ALPINE: ALPINE:
if: inputs.run_alpine if: inputs.run_alpine
name: ALPINE_X64_ASAN_UBSAN_DEBUG_ZTS name: ALPINE_X64_ASAN_UBSAN_DEBUG_ZTS
@ -95,7 +93,7 @@ jobs:
image: 'alpine:3.20.1' image: 'alpine:3.20.1'
steps: steps:
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: apk - name: apk
@ -134,9 +132,8 @@ jobs:
jitType: tracing jitType: tracing
runTestsParameters: >- runTestsParameters: >-
--asan -x --asan -x
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
- name: Extra tests
uses: ./.github/actions/extra-tests
- name: Notify Slack - name: Notify Slack
if: failure() if: failure()
uses: ./.github/actions/notify-slack uses: ./.github/actions/notify-slack
@ -206,7 +203,7 @@ jobs:
runs-on: ubuntu-${{ matrix.asan && inputs.asan_ubuntu_version || inputs.ubuntu_version }} runs-on: ubuntu-${{ matrix.asan && inputs.asan_ubuntu_version || inputs.ubuntu_version }}
steps: steps:
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Create MSSQL container - name: Create MSSQL container
@ -249,12 +246,14 @@ jobs:
jitType: tracing jitType: tracing
runTestsParameters: >- runTestsParameters: >-
${{ matrix.run_tests_parameters }} ${{ matrix.run_tests_parameters }}
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
- name: Test OpCache - name: Test OpCache
uses: ./.github/actions/test-linux uses: ./.github/actions/test-linux
with: with:
runTestsParameters: >- runTestsParameters: >-
${{ matrix.run_tests_parameters }} ${{ matrix.run_tests_parameters }}
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
- name: Test Function JIT - name: Test Function JIT
# ASAN frequently timeouts. Each test run takes ~90 minutes, we can # ASAN frequently timeouts. Each test run takes ~90 minutes, we can
@ -265,9 +264,8 @@ jobs:
jitType: function jitType: function
runTestsParameters: >- runTestsParameters: >-
${{ matrix.run_tests_parameters }} ${{ matrix.run_tests_parameters }}
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
- name: Extra tests
uses: ./.github/actions/extra-tests
- name: Verify generated files are up to date - name: Verify generated files are up to date
uses: ./.github/actions/verify-generated-files uses: ./.github/actions/verify-generated-files
- name: Notify Slack - name: Notify Slack
@ -306,7 +304,7 @@ jobs:
FIREBIRD_PASSWORD: test FIREBIRD_PASSWORD: test
steps: steps:
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: apt - name: apt
@ -340,12 +338,14 @@ jobs:
jitType: tracing jitType: tracing
runTestsParameters: >- runTestsParameters: >-
${{ matrix.run_tests_parameters }} ${{ matrix.run_tests_parameters }}
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
- name: Test OpCache - name: Test OpCache
uses: ./.github/actions/test-linux uses: ./.github/actions/test-linux
with: with:
runTestsParameters: >- runTestsParameters: >-
${{ matrix.run_tests_parameters }} ${{ matrix.run_tests_parameters }}
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
- name: Test Function JIT - name: Test Function JIT
uses: ./.github/actions/test-linux uses: ./.github/actions/test-linux
@ -353,9 +353,8 @@ jobs:
jitType: function jitType: function
runTestsParameters: >- runTestsParameters: >-
${{ matrix.run_tests_parameters }} ${{ matrix.run_tests_parameters }}
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
- name: Extra tests
uses: ./.github/actions/extra-tests
- name: Notify Slack - name: Notify Slack
if: failure() if: failure()
uses: ./.github/actions/notify-slack uses: ./.github/actions/notify-slack
@ -374,7 +373,7 @@ jobs:
runs-on: macos-${{ matrix.os }} runs-on: macos-${{ matrix.os }}
steps: steps:
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: brew - name: brew
@ -399,11 +398,13 @@ jobs:
with: with:
jitType: tracing jitType: tracing
runTestsParameters: >- runTestsParameters: >-
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
- name: Test OpCache - name: Test OpCache
uses: ./.github/actions/test-macos uses: ./.github/actions/test-macos
with: with:
runTestsParameters: >- runTestsParameters: >-
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
- name: Test Function JIT - name: Test Function JIT
if: matrix.os != '14' || !matrix.zts if: matrix.os != '14' || !matrix.zts
@ -411,9 +412,8 @@ jobs:
with: with:
jitType: function jitType: function
runTestsParameters: >- runTestsParameters: >-
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
- name: Extra tests
uses: ./.github/actions/extra-tests
- name: Verify generated files are up to date - name: Verify generated files are up to date
uses: ./.github/actions/verify-generated-files uses: ./.github/actions/verify-generated-files
- name: Notify Slack - name: Notify Slack
@ -449,7 +449,7 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Create MSSQL container - name: Create MSSQL container
@ -474,6 +474,7 @@ jobs:
with: with:
jitType: tracing jitType: tracing
runTestsParameters: >- runTestsParameters: >-
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
- uses: codecov/codecov-action@v4 - uses: codecov/codecov-action@v4
if: ${{ !cancelled() }} if: ${{ !cancelled() }}
@ -502,7 +503,7 @@ jobs:
USE_TRACKED_ALLOC: 1 USE_TRACKED_ALLOC: 1
steps: steps:
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: apt - name: apt
@ -527,6 +528,7 @@ jobs:
- name: Enable Opcache - name: Enable Opcache
run: | run: |
echo memory_limit=-1 >> /etc/php.d/opcache.ini 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_cli=1 >> /etc/php.d/opcache.ini
echo opcache.enable=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 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" repositories="amp cache dns file http parallel parser pipeline process serialization socket sync websocket-client websocket-server"
X=0 X=0
for repository in $repositories; do 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 git clone "https://github.com/amphp/$repository.git" "amphp-$repository" --depth 1
cd "amphp-$repository" cd "amphp-$repository"
git rev-parse HEAD git rev-parse HEAD
php /usr/bin/composer install --no-progress --ignore-platform-req=php+ php /usr/bin/composer install --no-progress --ignore-platform-req=php+
EXIT_CODE=0
vendor/bin/phpunit || EXIT_CODE=$? vendor/bin/phpunit || EXIT_CODE=$?
echo -e "\n::endgroup::"
if [ ${EXIT_CODE:-0} -gt 128 ]; then if [ ${EXIT_CODE:-0} -gt 128 ]; then
X=1; X=1;
echo "Failed"
fi fi
cd .. cd ..
done done
@ -587,17 +586,14 @@ jobs:
repositories="async cache child-process datagram dns event-loop promise promise-stream promise-timer stream" repositories="async cache child-process datagram dns event-loop promise promise-stream promise-timer stream"
X=0 X=0
for repository in $repositories; do 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 git clone "https://github.com/reactphp/$repository.git" "reactphp-$repository" --depth 1
cd "reactphp-$repository" cd "reactphp-$repository"
git rev-parse HEAD git rev-parse HEAD
php /usr/bin/composer install --no-progress --ignore-platform-req=php+ php /usr/bin/composer install --no-progress --ignore-platform-req=php+
EXIT_CODE=0
vendor/bin/phpunit || EXIT_CODE=$? vendor/bin/phpunit || EXIT_CODE=$?
echo -e "\n::endgroup::"
if [ $[EXIT_CODE:-0} -gt 128 ]; then if [ $[EXIT_CODE:-0} -gt 128 ]; then
X=1; X=1;
echo "Failed"
fi fi
cd .. cd ..
done done
@ -622,19 +618,15 @@ jobs:
php /usr/bin/composer install --no-progress --ignore-platform-req=php+ php /usr/bin/composer install --no-progress --ignore-platform-req=php+
php ./phpunit install php ./phpunit install
# Test causes a heap-buffer-overflow but I cannot reproduce it locally... # 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 # 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 export SYMFONY_DEPRECATIONS_HELPER=max[total]=999
X=0 X=0
for component in $(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -printf '%h\n'); do for component in $(find src/Symfony -mindepth 2 -type f -name phpunit.xml.dist -printf '%h\n'); do
echo "::group::$component" php ./phpunit $component --exclude-group tty,benchmark,intl-data,transient --exclude-group skip || EXIT_CODE=$?
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::"
if [ ${EXIT_CODE:-0} -gt 128 ]; then if [ ${EXIT_CODE:-0} -gt 128 ]; then
X=1; X=1;
echo "Failed"
fi fi
done done
exit $X exit $X
@ -705,7 +697,7 @@ jobs:
runs-on: ubuntu-${{ inputs.ubuntu_version }} runs-on: ubuntu-${{ inputs.ubuntu_version }}
steps: steps:
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Create MSSQL container - name: Create MSSQL container
@ -727,18 +719,21 @@ jobs:
uses: ./.github/actions/test-linux uses: ./.github/actions/test-linux
with: with:
runTestsParameters: >- runTestsParameters: >-
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
--file-cache-prime --file-cache-prime
- name: Test File Cache (prime shm, use shm) - name: Test File Cache (prime shm, use shm)
uses: ./.github/actions/test-linux uses: ./.github/actions/test-linux
with: with:
runTestsParameters: >- runTestsParameters: >-
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
--file-cache-use --file-cache-use
- name: Test File Cache (prime shm, use file) - name: Test File Cache (prime shm, use file)
uses: ./.github/actions/test-linux uses: ./.github/actions/test-linux
with: with:
runTestsParameters: >- runTestsParameters: >-
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
--file-cache-use --file-cache-use
-d opcache.file_cache_only=1 -d opcache.file_cache_only=1
@ -746,6 +741,7 @@ jobs:
uses: ./.github/actions/test-linux uses: ./.github/actions/test-linux
with: with:
runTestsParameters: >- runTestsParameters: >-
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
--file-cache-prime --file-cache-prime
-d opcache.file_cache_only=1 -d opcache.file_cache_only=1
@ -753,6 +749,7 @@ jobs:
uses: ./.github/actions/test-linux uses: ./.github/actions/test-linux
with: with:
runTestsParameters: >- runTestsParameters: >-
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
--file-cache-use --file-cache-use
-d opcache.file_cache_only=1 -d opcache.file_cache_only=1
@ -768,7 +765,7 @@ jobs:
runs-on: ubuntu-${{ inputs.ubuntu_version }} runs-on: ubuntu-${{ inputs.ubuntu_version }}
steps: steps:
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: apt - name: apt
@ -846,6 +843,7 @@ jobs:
with: with:
runTestsParameters: >- runTestsParameters: >-
--msan --msan
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
- name: Verify generated files are up to date - name: Verify generated files are up to date
uses: ./.github/actions/verify-generated-files uses: ./.github/actions/verify-generated-files
@ -859,7 +857,7 @@ jobs:
runs-on: ubuntu-${{ inputs.ubuntu_version }} runs-on: ubuntu-${{ inputs.ubuntu_version }}
steps: steps:
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: apt - name: apt
@ -909,38 +907,38 @@ jobs:
CXX: ccache g++ CXX: ccache g++
steps: steps:
- name: git checkout PHP - name: git checkout PHP
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
path: php path: php
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: git checkout apcu - name: git checkout apcu
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
repository: krakjoe/apcu repository: krakjoe/apcu
path: apcu path: apcu
- name: git checkout imagick - name: git checkout imagick
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
repository: Imagick/imagick repository: Imagick/imagick
path: imagick path: imagick
- name: git checkout memcached - name: git checkout memcached
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
repository: php-memcached-dev/php-memcached repository: php-memcached-dev/php-memcached
path: memcached path: memcached
- name: git checkout redis - name: git checkout redis
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
repository: phpredis/phpredis repository: phpredis/phpredis
path: redis path: redis
- name: git checkout xdebug - name: git checkout xdebug
if: false if: false
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
repository: xdebug/xdebug repository: xdebug/xdebug
path: xdebug path: xdebug
- name: git checkout yaml - name: git checkout yaml
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
repository: php/pecl-file_formats-yaml repository: php/pecl-file_formats-yaml
path: yaml path: yaml
@ -1050,7 +1048,7 @@ jobs:
- name: git config - name: git config
run: git config --global core.autocrlf false && git config --global core.eol lf run: git config --global core.autocrlf false && git config --global core.eol lf
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: Setup - name: Setup
@ -1068,10 +1066,9 @@ jobs:
- zts: ${{ !inputs.run_freebsd_zts && true || '*never*' }} - zts: ${{ !inputs.run_freebsd_zts && true || '*never*' }}
name: "FREEBSD_${{ matrix.zts && 'ZTS' || 'NTS' }}" name: "FREEBSD_${{ matrix.zts && 'ZTS' || 'NTS' }}"
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 50
steps: steps:
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
ref: ${{ inputs.branch }} ref: ${{ inputs.branch }}
- name: FreeBSD - name: FreeBSD
@ -1079,4 +1076,3 @@ jobs:
with: with:
configurationParameters: >- configurationParameters: >-
--${{ matrix.zts && 'enable' || 'disable' }}-zts --${{ matrix.zts && 'enable' || 'disable' }}-zts
runExtraTests: true

View file

@ -10,12 +10,15 @@ on:
- CONTRIBUTING.md - CONTRIBUTING.md
- CODING_STANDARDS.md - CODING_STANDARDS.md
- .cirrus.yml - .cirrus.yml
- .travis.yml
- travis/**
- .circleci/** - .circleci/**
branches: branches:
- PHP-7.4
- PHP-8.0
- PHP-8.1 - PHP-8.1
- PHP-8.2 - PHP-8.2
- PHP-8.3 - PHP-8.3
- PHP-8.4
- master - master
pull_request: pull_request:
paths-ignore: paths-ignore:
@ -27,6 +30,8 @@ on:
- CONTRIBUTING.md - CONTRIBUTING.md
- CODING_STANDARDS.md - CODING_STANDARDS.md
- .cirrus.yml - .cirrus.yml
- .travis.yml
- travis/**
- .circleci/** - .circleci/**
branches: branches:
- '**' - '**'
@ -58,15 +63,6 @@ jobs:
POSTGRES_USER: postgres POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres POSTGRES_PASSWORD: postgres
POSTGRES_DB: test 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: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@ -78,11 +74,10 @@ jobs:
zts: true zts: true
asan: true asan: true
name: "LINUX_X64_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}${{ matrix.asan && '_ASAN' || '' }}" name: "LINUX_X64_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}${{ matrix.asan && '_ASAN' || '' }}"
runs-on: ubuntu-24.04 runs-on: ubuntu-${{ !matrix.asan && '22' || '24' }}.04
timeout-minutes: 50
steps: steps:
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: apt - name: apt
uses: ./.github/actions/apt-x64 uses: ./.github/actions/apt-x64
- name: System info - name: System info
@ -96,6 +91,9 @@ jobs:
- name: Create MSSQL container - name: Create MSSQL container
if: ${{ !matrix.asan }} if: ${{ !matrix.asan }}
uses: ./.github/actions/setup-mssql uses: ./.github/actions/setup-mssql
- name: Create Oracle container
if: ${{ !matrix.asan }}
uses: ./.github/actions/setup-oracle
- name: Setup Caddy server - name: Setup Caddy server
uses: ./.github/actions/setup-caddy uses: ./.github/actions/setup-caddy
- name: ccache - name: ccache
@ -113,7 +111,7 @@ jobs:
configurationParameters: >- configurationParameters: >-
--${{ matrix.debug && 'enable' || 'disable' }}-debug --${{ matrix.debug && 'enable' || 'disable' }}-debug
--${{ matrix.zts && 'enable' || 'disable' }}-zts --${{ 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 }} skipSlow: ${{ matrix.asan }}
- name: make - name: make
run: make -j$(/usr/bin/nproc) >/dev/null run: make -j$(/usr/bin/nproc) >/dev/null
@ -125,11 +123,12 @@ jobs:
- name: Test - name: Test
if: matrix.asan == false if: matrix.asan == false
uses: ./.github/actions/test-linux uses: ./.github/actions/test-linux
- name: Test Tracing JIT - name: Test ${{ matrix.asan && 'OpCache' || 'Tracing JIT' }}
uses: ./.github/actions/test-linux uses: ./.github/actions/test-linux
with: with:
jitType: tracing jitType: ${{ matrix.asan && 'disable' || 'tracing' }}
runTestsParameters: >- runTestsParameters: >-
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
${{ matrix.asan && '--asan -x' || '' }} ${{ matrix.asan && '--asan -x' || '' }}
- name: Verify generated files are up to date - name: Verify generated files are up to date
@ -139,14 +138,12 @@ jobs:
if: github.repository == 'php/php-src' || github.event_name == 'pull_request' if: github.repository == 'php/php-src' || github.event_name == 'pull_request'
name: LINUX_X32_DEBUG_ZTS name: LINUX_X32_DEBUG_ZTS
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 50
container: container:
image: ubuntu:24.04 image: ubuntu:22.04
env: env:
MYSQL_TEST_HOST: mysql MYSQL_TEST_HOST: mysql
PDO_MYSQL_TEST_DSN: mysql:host=mysql;dbname=test PDO_MYSQL_TEST_DSN: mysql:host=mysql;dbname=test
PDO_MYSQL_TEST_HOST: mysql PDO_MYSQL_TEST_HOST: mysql
PDO_FIREBIRD_TEST_DSN: firebird:dbname=firebird:test.fdb
services: services:
mysql: mysql:
image: mysql:8.3 image: mysql:8.3
@ -155,18 +152,9 @@ jobs:
env: env:
MYSQL_DATABASE: test MYSQL_DATABASE: test
MYSQL_ROOT_PASSWORD: root 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: steps:
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: apt - name: apt
uses: ./.github/actions/apt-x32 uses: ./.github/actions/apt-x32
- name: ccache - name: ccache
@ -189,27 +177,20 @@ jobs:
with: with:
jitType: tracing jitType: tracing
runTestsParameters: >- runTestsParameters: >-
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
MACOS_DEBUG_NTS: MACOS_DEBUG_NTS:
if: github.repository == 'php/php-src' || github.event_name == 'pull_request' if: github.repository == 'php/php-src' || github.event_name == 'pull_request'
strategy: runs-on: macos-13
fail-fast: false
matrix:
include:
- os: 15
arch: ARM64
name: MACOS_${{ matrix.arch }}_DEBUG_NTS
runs-on: macos-${{ matrix.os }}
timeout-minutes: 50
steps: steps:
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: brew - name: brew
uses: ./.github/actions/brew uses: ./.github/actions/brew
- name: ccache - name: ccache
uses: hendrikmuhs/ccache-action@v1.2 uses: hendrikmuhs/ccache-action@v1.2
with: with:
key: "${{github.job}}-${{matrix.os}}-${{hashFiles('main/php_version.h')}}" key: "${{github.job}}-${{hashFiles('main/php_version.h')}}"
append-timestamp: false append-timestamp: false
save: ${{ github.event_name != 'pull_request' }} save: ${{ github.event_name != 'pull_request' }}
- name: ./configure - name: ./configure
@ -218,7 +199,7 @@ jobs:
configurationParameters: --enable-debug --disable-zts configurationParameters: --enable-debug --disable-zts
- name: make - name: make
run: |- 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 make -j$(sysctl -n hw.logicalcpu) >/dev/null
- name: make install - name: make install
run: sudo make install run: sudo make install
@ -227,20 +208,21 @@ jobs:
with: with:
jitType: tracing jitType: tracing
runTestsParameters: >- runTestsParameters: >-
-d zend_extension=opcache.so
-d opcache.enable_cli=1 -d opcache.enable_cli=1
-d opcache.protect_memory=1
- name: Verify generated files are up to date - name: Verify generated files are up to date
uses: ./.github/actions/verify-generated-files uses: ./.github/actions/verify-generated-files
WINDOWS: WINDOWS:
if: github.repository == 'php/php-src' || github.event_name == 'pull_request' if: github.repository == 'php/php-src' || github.event_name == 'pull_request'
name: WINDOWS_X64_ZTS name: WINDOWS_X64_ZTS
runs-on: windows-2022 runs-on: windows-2022
timeout-minutes: 50
env: env:
PHP_BUILD_CACHE_BASE_DIR: C:\build-cache PHP_BUILD_CACHE_BASE_DIR: C:\build-cache
PHP_BUILD_OBJ_DIR: C:\obj PHP_BUILD_OBJ_DIR: C:\obj
PHP_BUILD_CACHE_SDK_DIR: C:\build-cache\sdk PHP_BUILD_CACHE_SDK_DIR: C:\build-cache\sdk
PHP_BUILD_SDK_BRANCH: php-sdk-2.3.0 PHP_BUILD_SDK_BRANCH: php-sdk-2.3.0
PHP_BUILD_CRT: vs17 PHP_BUILD_CRT: vs16
PLATFORM: x64 PLATFORM: x64
THREAD_SAFE: "1" THREAD_SAFE: "1"
INTRINSICS: AVX2 INTRINSICS: AVX2
@ -250,7 +232,7 @@ jobs:
- name: git config - name: git config
run: git config --global core.autocrlf false && git config --global core.eol lf run: git config --global core.autocrlf false && git config --global core.eol lf
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: Setup - name: Setup
uses: ./.github/actions/setup-windows uses: ./.github/actions/setup-windows
- name: Build - name: Build
@ -260,17 +242,12 @@ jobs:
BENCHMARKING: BENCHMARKING:
name: BENCHMARKING name: BENCHMARKING
if: github.repository == 'php/php-src' || github.event_name == 'pull_request' if: github.repository == 'php/php-src' || github.event_name == 'pull_request'
runs-on: ubuntu-24.04 runs-on: ubuntu-22.04
timeout-minutes: 50
steps: steps:
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
fetch-depth: 0 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 - name: apt
run: | run: |
set -x set -x
@ -296,6 +273,7 @@ jobs:
./configure \ ./configure \
--disable-debug \ --disable-debug \
--enable-mbstring \ --enable-mbstring \
--enable-opcache \
--enable-option-checking=fatal \ --enable-option-checking=fatal \
--enable-sockets \ --enable-sockets \
--enable-werror \ --enable-werror \
@ -315,6 +293,7 @@ jobs:
sudo mkdir -p /etc/php.d sudo mkdir -p /etc/php.d
sudo chmod 777 /etc/php.d sudo chmod 777 /etc/php.d
echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini 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=1 >> /etc/php.d/opcache.ini
echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini
- name: Setup - name: Setup
@ -326,7 +305,7 @@ jobs:
mysql -uroot -proot -e "CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'wordpress'; FLUSH PRIVILEGES;" 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;" mysql -uroot -proot -e "GRANT ALL PRIVILEGES ON *.* TO 'wordpress'@'localhost' WITH GRANT OPTION;"
- name: git checkout benchmarking-data - name: git checkout benchmarking-data
uses: actions/checkout@v5 uses: actions/checkout@v4
with: with:
repository: php/benchmarking-data repository: php/benchmarking-data
ssh-key: ${{ secrets.BENCHMARKING_DATA_DEPLOY_KEY }} ssh-key: ${{ secrets.BENCHMARKING_DATA_DEPLOY_KEY }}
@ -357,18 +336,12 @@ jobs:
${{ github.sha }} \ ${{ github.sha }} \
$(git merge-base ${{ github.event.pull_request.base.sha }} ${{ github.sha }}) \ $(git merge-base ${{ github.event.pull_request.base.sha }} ${{ github.sha }}) \
> $GITHUB_STEP_SUMMARY > $GITHUB_STEP_SUMMARY
- uses: actions/upload-artifact@v4
with:
name: profiles
path: ${{ github.workspace }}/benchmark/profiles
retention-days: 30
FREEBSD: FREEBSD:
if: github.repository == 'php/php-src' || github.event_name == 'pull_request' if: github.repository == 'php/php-src' || github.event_name == 'pull_request'
name: FREEBSD name: FREEBSD
runs-on: ubuntu-latest runs-on: ubuntu-latest
timeout-minutes: 50
steps: steps:
- name: git checkout - name: git checkout
uses: actions/checkout@v5 uses: actions/checkout@v4
- name: FreeBSD - name: FreeBSD
uses: ./.github/actions/freebsd uses: ./.github/actions/freebsd

View file

@ -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

View file

@ -10,7 +10,7 @@ permissions:
jobs: jobs:
build: 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 runs-on: ubuntu-latest
permissions: permissions:
issues: write issues: write

View file

@ -13,7 +13,7 @@ jobs:
outputs: outputs:
branches: ${{ steps.set-matrix.outputs.branches }} branches: ${{ steps.set-matrix.outputs.branches }}
steps: steps:
- uses: actions/checkout@v5 - uses: actions/checkout@v4
with: with:
# Set fetch-depth to 0 to clone the full repository # Set fetch-depth to 0 to clone the full repository
# including all branches. This is required to find # including all branches. This is required to find

21
.gitignore vendored
View file

@ -81,7 +81,8 @@ Makefile
Makefile.fragments Makefile.fragments
Makefile.objects Makefile.objects
# Directories for shared object files generated by `./configure` # Directories for shared object files and headers generated by `./configure`
include/
libs/ libs/
modules/ modules/
@ -131,7 +132,6 @@ config.h.in
/sapi/cgi/php-cgi /sapi/cgi/php-cgi
/sapi/fpm/php-fpm /sapi/fpm/php-fpm
/sapi/phpdbg/phpdbg /sapi/phpdbg/phpdbg
/sapi/fuzzer/php-fuzz-*
/scripts/php-config /scripts/php-config
/scripts/phpize /scripts/phpize
php php
@ -141,7 +141,7 @@ php
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
/ext/json/json_scanner.c /ext/json/json_scanner.c
/ext/json/php_json_scanner_defs.h /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/phar/phar_path_check.c
/ext/standard/url_scanner_ex.c /ext/standard/url_scanner_ex.c
/ext/standard/var_unserializer.c /ext/standard/var_unserializer.c
@ -171,7 +171,6 @@ php
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Miscellaneous extensions files # Miscellaneous extensions files
/ext/fileinfo/libmagic.orig/
/ext/opcache/jit/zend_jit_x86.c /ext/opcache/jit/zend_jit_x86.c
/ext/opcache/jit/zend_jit_arm64.c /ext/opcache/jit/zend_jit_arm64.c
/ext/opcache/minilua /ext/opcache/minilua
@ -238,7 +237,6 @@ php
**/tests/**/*.exp **/tests/**/*.exp
**/tests/**/*.log **/tests/**/*.log
**/tests/**/*.sh **/tests/**/*.sh
**/tests/**/*.stdin
# Generated by some test cases # Generated by some test cases
**/tests/**/*.db **/tests/**/*.db
@ -262,7 +260,7 @@ phpt.*
tmp-php.ini 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 *.gcda
*.gcno *.gcno
@ -274,7 +272,6 @@ tmp-php.ini
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Archives generated during the PHP release process # Archives generated during the PHP release process
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
/*.manifest
/*.tar.gz /*.tar.gz
/*.tar.bz2 /*.tar.bz2
/*.tar.xz /*.tar.xz
@ -285,6 +282,8 @@ tmp-php.ini
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Generated by `./configure --enable-dtrace` for using DTrace framework # 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
/Zend/zend_dtrace_gen.h.bak /Zend/zend_dtrace_gen.h.bak
@ -295,13 +294,6 @@ tmp-php.ini
/junit.out.xml /junit.out.xml
/.ccache/ /.ccache/
# ------------------------------------------------------------------------------
# Editor configuration directories
# ------------------------------------------------------------------------------
/.idea/
/.vscode/
/.zed/
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Additional test build files # Additional test build files
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -314,6 +306,5 @@ tmp-php.ini
!/ext/fileinfo/libmagic/config.h !/ext/fileinfo/libmagic/config.h
!/ext/fileinfo/libmagic.patch !/ext/fileinfo/libmagic.patch
!/ext/fileinfo/magicdata.patch !/ext/fileinfo/magicdata.patch
!/ext/lexbor/patches/*.patch
!/ext/pcre/pcre2lib/config.h !/ext/pcre/pcre2lib/config.h
!/win32/build/Makefile !/win32/build/Makefile

92
.travis.yml Normal file
View 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

View file

@ -9,10 +9,9 @@ rewritten to comply with these rules.
1. Document your code in source files and the manual. (tm) 1. Document your code in source files and the manual. (tm)
1. PHP is implemented in C11. 1. PHP is implemented in C99. The optional fixed-width integers from
For instance, the optional fixed-width integers from
stdint.h (int8_t, int16_t, int32_t, int64_t and their unsigned 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. 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_*` 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. 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 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 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 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 1. Method names follow the *studlyCaps* (also referred to as *bumpy case* or
*camel caps*) naming convention, with care taken to minimize the letter *camel caps*) naming convention, with care taken to minimize the letter
count. The initial letter of the name is lowercase, and each letter that 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 Good:
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:
```php ```php
connect() connect()
getData() getData()
buildSomeWidget() buildSomeWidget()
performHttpRequest()
``` ```
Bad method names: Bad:
```php ```php
get_Data() get_Data()
buildsomewidget() buildsomewidget()
getI() 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 ```php
Curl Curl
CurlResponse CurlResponse
HttpStatusCode HTTPStatusCode
Url URL
BtreeMap // B-tree Map BTreeMap // B-tree Map
UserId // User Identifier Id // Identifier
ID // Identity Document
Char // Character Char // Character
Intl // Internationalization Intl // Internationalization
Ssl\Certificate Radar // Radio Detecting and Ranging
Ssl\Crl // Certificate Revocation List
Ssl\CrlUrl
``` ```
Bad class names: Bad:
```php ```php
curl curl
curl_response curl_response
HTTPStatusCode HttpStatusCode
URL Url
BTreeMap BtreeMap
UserID // User Identifier ID // Identifier
CHAR CHAR
INTL INTL
SSL\Certificate RADAR // Radio Detecting and Ranging
SSL\CRL
SSL\CRLURL
``` ```
## Internal function naming conventions ## Internal function naming conventions

View file

@ -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 PHP welcomes pull requests to [add tests](#writing-tests), fix bugs and to
implement RFCs. Please be sure to include tests as appropriate! 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 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 supported branch of PHP that the bug affects (only green branches on
[the supported version page](https://www.php.net/supported-versions.php) are [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 ## Writing documentation
Editing the manual is done by checking out the XML sources using Git and editing There are two ways to contribute to the PHP manual. You can edit the manual and
and building it [per the instructions on the documentation site](http://doc.php.net/tutorial/). 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 ## Getting help
@ -208,9 +206,6 @@ locations.
├─ libmbfl/ # Forked and maintained in php-src ├─ libmbfl/ # Forked and maintained in php-src
├─ unicode_data.h # Generated by `ext/mbstring/ucgendat/ucgendat.php` ├─ unicode_data.h # Generated by `ext/mbstring/ucgendat/ucgendat.php`
└─ ... └─ ...
└─ opcache/
└─ jit/
└─ ir/ # Bundled part of IR framework https://github.com/dstogov/ir
└─ pcre/ └─ pcre/
├─ pcre2lib/ # https://www.pcre.org/ ├─ pcre2lib/ # https://www.pcre.org/
└─ ... └─ ...
@ -244,6 +239,7 @@ locations.
└─ ... └─ ...
├─ scripts/ # php-config, phpize and internal development scripts ├─ scripts/ # php-config, phpize and internal development scripts
├─ tests/ # Core features tests ├─ tests/ # Core features tests
├─ travis/ # Travis CI service files
└─ win32/ # Windows build system files └─ win32/ # Windows build system files
├─ cp_enc_map.c # Generated by `win32/cp_enc_map_gen.exe` ├─ 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 | | | Branch | |
| --------- | --------- | | --------- | --------- |
| master | Active development branch for PHP 8.5, which is open for backwards incompatible changes and major internal API changes. | | master | Active development branch for PHP 8.3, 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.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.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.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.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.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-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. |
| PHP-7.4 | This branch is closed. | | PHP-7.4 | This branch is closed. |
| PHP-7.3 | This branch is closed. | | PHP-7.3 | This branch is closed. |
| PHP-7.2 | This branch is closed. | | PHP-7.2 | This branch is closed. |

View file

@ -93,9 +93,14 @@ MAINTENANCE: Maintained
STATUS: Working STATUS: Working
SINCE: 5.3 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 EXTENSION: odbc
PRIMARY MAINTAINER: Daniel R. Kalowsky <kalowsky@php.net> (2000 - 2004) PRIMARY MAINTAINER: Daniel R. Kalowsky <kalowsky@php.net> (2000 - 2004)
Calvin Buckley <calvin@cmpct.info> (2024 - )
MAINTENANCE: Maintained MAINTENANCE: Maintained
STATUS: Working STATUS: Working
COMMENT: Working COMMENT: Working
@ -129,8 +134,14 @@ STATUS: Working
SINCE: 5.1 SINCE: 5.1
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
EXTENSION: pdo_odbc EXTENSION: pdo_odbc
PRIMARY MAINTAINER: Calvin Buckley <calvin@cmpct.info> (2024 - ) PRIMARY MAINTAINER: Unknown
MAINTENANCE: Maintained 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 STATUS: Working
SINCE: 5.1 SINCE: 5.1
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@ -195,13 +206,6 @@ PRIMARY MAINTAINER: Thies C. Arntzen <thies@thieso.net> (1999 - 2002)
MAINTENANCE: Maintained MAINTENANCE: Maintained
STATUS: Working 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 EXTENSION: libxml
PRIMARY MAINTAINER: Rob Richards <rrichards@php.net> (2003 - 2009) PRIMARY MAINTAINER: Rob Richards <rrichards@php.net> (2003 - 2009)
Christian Stocker <chregu@php.net> (2004 - 2011) Christian Stocker <chregu@php.net> (2004 - 2011)
@ -238,7 +242,6 @@ SINCE: 5.0
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
EXTENSION: bcmath EXTENSION: bcmath
PRIMARY MAINTAINER: Andi Gutmans <andi@php.net> (2000 - 2004) PRIMARY MAINTAINER: Andi Gutmans <andi@php.net> (2000 - 2004)
Saki Takamachi <saki@php.net> (2024 - 2025)
MAINTENANCE: Maintained MAINTENANCE: Maintained
STATUS: Working STATUS: Working
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@ -355,6 +358,14 @@ MAINTENANCE: Maintained
STATUS: Working STATUS: Working
SINCE: 5.3 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 EXTENSION: json
PRIMARY MAINTAINER: Jakub Zelenka <bukka@php.net> (2014 - 2018) PRIMARY MAINTAINER: Jakub Zelenka <bukka@php.net> (2014 - 2018)
MAINTENANCE: Maintained MAINTENANCE: Maintained
@ -372,8 +383,7 @@ STATUS: Working
EXTENSION: mbstring EXTENSION: mbstring
PRIMARY MAINTAINER: Rui Hirokawa <hirokawa@php.net> (2001 - 2013) PRIMARY MAINTAINER: Rui Hirokawa <hirokawa@php.net> (2001 - 2013)
Nikita Popov <nikic@php.net> (2017 - 2020) Nikita Popov <nikic@php.net> (2017 - 2020)
Alex Dowad <alexinbeijing@gmail.com> (2021 - 2024) Alex Dowad <alexinbeijing@gmail.com> (2021 - 2022)
Yuya Hamada <youkidearitai@gmail.com> (2024 - 2024)
MAINTENANCE: Maintained MAINTENANCE: Maintained
STATUS: Working STATUS: Working
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@ -418,9 +428,15 @@ PRIMARY MAINTAINER: Kristian Köhntopp <kris@koehntopp.de> (2000 - 2000)
MAINTENANCE: Maintained MAINTENANCE: Maintained
STATUS: Working STATUS: Working
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
EXTENSION: pspell
PRIMARY MAINTAINER: Vlad Krupin <phpdevel@echospace.com> (2000 - 2004)
MAINTENANCE: Unknown
STATUS: Working
SINCE: 4.0.2
-------------------------------------------------------------------------------
EXTENSION: random EXTENSION: random
PRIMARY MAINTAINER Go Kudo <zeriyoshi@php.net> (2022 - 2024) PRIMARY MAINTAINER Go Kudo <zeriyoshi@php.net> (2022 - 2022)
Tim Düsterhus <timwolla@php.net> (2022 - 2025) Tim Düsterhus <timwolla@php.net> (2022 - 2023)
MAINTENANCE: Maintained MAINTENANCE: Maintained
STATUS: Working STATUS: Working
SINCE: 8.2.0 SINCE: 8.2.0
@ -434,7 +450,6 @@ EXTENSION: reflection
PRIMARY MAINTAINER: Marcus Börger <helly@php.net> (2003 - 2009) PRIMARY MAINTAINER: Marcus Börger <helly@php.net> (2003 - 2009)
Johannes Schlüter <johannes@php.net> (2006 - 2014) Johannes Schlüter <johannes@php.net> (2006 - 2014)
Nikita Popov <nikic@php.net> (2019 - 2020) Nikita Popov <nikic@php.net> (2019 - 2020)
Daniel Scherzer <daniel.e.scherzer@gmail.com> (2025 - 2025)
MAINTENANCE: Maintained MAINTENANCE: Maintained
STATUS: Working STATUS: Working
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@ -504,12 +519,6 @@ PRIMARY MAINTAINER: Andrei Zmievski <andrei@php.net> (2002 - 2002)
MAINTENANCE: Maintained MAINTENANCE: Maintained
STATUS: Working STATUS: Working
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
EXTENSION: uri
PRIMARY MAINTAINER Máté Kocsis <kocsismate@php.net> (2025 - 2025)
MAINTENANCE: Maintained
STATUS: Working
SINCE: 8.5.0
-------------------------------------------------------------------------------
EXTENSION: zip EXTENSION: zip
PRIMARY MAINTAINER: Pierre-Alain Joye <pajoye@php.net> (2006 - 2011) PRIMARY MAINTAINER: Pierre-Alain Joye <pajoye@php.net> (2006 - 2011)
Remi Collet <remi@php.net> (2013-2020) Remi Collet <remi@php.net> (2013-2020)

2534
NEWS

File diff suppressed because it is too large Load diff

View file

@ -17,9 +17,7 @@
17. ext/mbstring/ucgendat portions based on the ucgendat.c from the OpenLDAP 17. ext/mbstring/ucgendat portions based on the ucgendat.c from the OpenLDAP
18. avifinfo (ext/standard/libavifinfo) see ext/standard/libavifinfo/LICENSE 18. avifinfo (ext/standard/libavifinfo) see ext/standard/libavifinfo/LICENSE
19. xxHash (ext/hash/xxhash) 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) 3. pcre2lib (ext/pcre)

View file

@ -1,5 +1,5 @@
<div align="center"> <div align="center">
<a href="https://www.php.net"> <a href="https://php.net">
<img <img
alt="PHP" alt="PHP"
src="https://www.php.net/images/logos/new-php-logo.svg" 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). [PHP License v3.01](LICENSE).
[![Push](https://github.com/php/php-src/actions/workflows/push.yml/badge.svg)](https://github.com/php/php-src/actions/workflows/push.yml) [![Push](https://github.com/php/php-src/actions/workflows/push.yml/badge.svg)](https://github.com/php/php-src/actions/workflows/push.yml)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/php.svg)](https://issues.oss-fuzz.com/issues?q=project:php) [![Build status](https://travis-ci.com/php/php-src.svg?branch=master)](https://travis-ci.com/github/php/php-src)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/php.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:php)
## Documentation ## 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 ## 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 [windows.php.net](https://windows.php.net). After extracting the archive the
`*.exe` files are ready to use. `*.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 ### 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: On Ubuntu, you can install these using:
```shell sudo apt install -y pkg-config build-essential autoconf bison re2c \
sudo apt install -y pkg-config build-essential autoconf bison re2c libxml2-dev libsqlite3-dev libxml2-dev libsqlite3-dev
```
On Fedora, you can install these using: On Fedora, you can install these using:
```shell sudo dnf install re2c bison autoconf make libtool ccache libxml2-devel sqlite-devel
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: Generate configure:
```shell ./buildconf
./buildconf
```
Configure your build. `--enable-debug` is recommended for development, see Configure your build. `--enable-debug` is recommended for development, see
`./configure --help` for a full list of options. `./configure --help` for a full list of options.
```shell # For development
# For development ./configure --enable-debug
./configure --enable-debug # For production
# For production ./configure
./configure
```
Build PHP. To speed up the build, specify the maximum number of jobs using the Build PHP. To speed up the build, specify the maximum number of jobs using `-j`:
`-j` argument:
```shell make -j4
make -j4
```
The number of jobs should usually match the number of available cores, which The number of jobs should usually match the number of available cores, which
can be determined using `nproc`. 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. successful compilation of the sources to run this test suite.
It is possible to run tests using multiple cores by setting `-jN` in 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
make TEST_PHP_ARGS=-j4 test
```
Shall run `make test` with a maximum of 4 concurrent jobs: Generally the maximum 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. 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 The [qa.php.net](https://qa.php.net) site provides more detailed info about
testing and quality assurance. testing and quality assurance.
@ -118,11 +89,9 @@ testing and quality assurance.
After a successful build (and test), PHP may be installed with: After a successful build (and test), PHP may be installed with:
```shell make install
make install
```
Depending on your permissions and prefix, `make install` may need superuser Depending on your permissions and prefix, `make install` may need super user
permissions. permissions.
## PHP extensions ## PHP extensions
@ -162,11 +131,10 @@ contribute:
- [Contributing to PHP](/CONTRIBUTING.md) - [Contributing to PHP](/CONTRIBUTING.md)
- [PHP coding standards](/CODING_STANDARDS.md) - [PHP coding standards](/CODING_STANDARDS.md)
- [Internal documentation](https://php.github.io/php-src/)
- [Mailing list rules](/docs/mailinglist-rules.md) - [Mailing list rules](/docs/mailinglist-rules.md)
- [PHP release process](/docs/release-process.md) - [PHP release process](/docs/release-process.md)
## Credits ## Credits
For the list of people who've put work into PHP, please see the 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).

View file

@ -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_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 * 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 ??? // TODO: Implement support for fast JIT ZTS code ???
return 0; return 0;
#elif defined(__x86_64__) && defined(__GNUC__) && !defined(__FreeBSD__) && \ #elif defined(__x86_64__) && defined(__GNUC__) && !defined(__FreeBSD__) && \
!defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) && \ !defined(__OpenBSD__) && !defined(__MUSL__) && !defined(__HAIKU__)
!defined(__HAIKU__) && !defined(__CYGWIN__)
size_t ret; size_t ret;
asm ("movq _tsrm_ls_cache@gottpoff(%%rip),%0" asm ("movq _tsrm_ls_cache@gottpoff(%%rip),%0"
: "=r" (ret)); : "=r" (ret));
return ret; return ret;
#elif defined(__i386__) && defined(__GNUC__) && !defined(__FreeBSD__) && \ #elif defined(__i386__) && defined(__GNUC__) && !defined(__FreeBSD__) && \
!defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) && \ !defined(__OpenBSD__) && !defined(__MUSL__) && !defined(__HAIKU__)
!defined(__HAIKU__) && !defined(__CYGWIN__)
size_t ret; size_t ret;
asm ("leal _tsrm_ls_cache@ntpoff,%0" asm ("leal _tsrm_ls_cache@ntpoff,%0"

View file

@ -13,11 +13,11 @@
#ifndef TSRM_H #ifndef TSRM_H
#define TSRM_H #define TSRM_H
#if !defined(__CYGWIN__) && defined(_WIN32) #if !defined(__CYGWIN__) && defined(WIN32)
# define TSRM_WIN32 # define TSRM_WIN32
# include <Zend/zend_config.w32.h> # include "Zend/zend_config.w32.h"
#else #else
# include <main/php_config.h> # include "main/php_config.h"
#endif #endif
#include <stdint.h> #include <stdint.h>
@ -104,9 +104,6 @@ TSRM_API void ts_free_thread(void);
/* deallocates all occurrences of a given id */ /* deallocates all occurrences of a given id */
TSRM_API void ts_free_id(ts_rsrc_id 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 */ /* Debug support */
#define TSRM_ERROR_LEVEL_ERROR 1 #define TSRM_ERROR_LEVEL_ERROR 1
@ -152,7 +149,7 @@ TSRM_API bool tsrm_is_managed_thread(void);
# define __has_attribute(x) 0 # define __has_attribute(x) 0
#endif #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_ATTR
# define TSRM_TLS_MODEL_DEFAULT # define TSRM_TLS_MODEL_DEFAULT
#elif __PIC__ #elif __PIC__

View file

@ -31,6 +31,12 @@ dnl
dnl Set some magic defines to achieve POSIX threads conformance. dnl Set some magic defines to achieve POSIX threads conformance.
dnl dnl
AC_DEFUN([PTHREADS_FLAGS],[ 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 case $host_alias in
*solaris*) *solaris*)
PTHREAD_FLAGS="-D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT";; PTHREAD_FLAGS="-D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT";;
@ -40,6 +46,8 @@ AC_DEFUN([PTHREADS_FLAGS],[
PTHREAD_FLAGS=-D_REENTRANT;; PTHREAD_FLAGS=-D_REENTRANT;;
*aix*) *aix*)
PTHREAD_FLAGS=-D_THREAD_SAFE;; PTHREAD_FLAGS=-D_THREAD_SAFE;;
*irix*)
PTHREAD_FLAGS=-D_POSIX_THREAD_SAFE_FUNCTIONS;;
*hpux*) *hpux*)
PTHREAD_FLAGS=-D_REENTRANT;; PTHREAD_FLAGS=-D_REENTRANT;;
*sco*) *sco*)
@ -126,7 +134,7 @@ if test "$pthreads_working" != "yes"; then
fi 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" pthreads_working="yes"
fi fi
]) ])

17
TSRM/tsrm.m4 Normal file
View 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)
])

View file

@ -481,13 +481,12 @@ TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd,
return NULL; return NULL;
} }
size_t cmd_buffer_size = strlen(command) + strlen(TWG(comspec)) + sizeof(" /s /c ") + 2; cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /s /c ")+2);
cmd = malloc(cmd_buffer_size);
if (!cmd) { if (!cmd) {
return NULL; 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); cmdw = php_win32_cp_any_to_w(cmd);
if (!cmdw) { if (!cmdw) {
free(cmd); free(cmd);
@ -636,7 +635,7 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
{/*{{{*/ {/*{{{*/
shm_pair *shm; shm_pair *shm;
char shm_segment[sizeof(SEGMENT_PREFIX INT_MIN_AS_STRING)]; char shm_segment[sizeof(SEGMENT_PREFIX INT_MIN_AS_STRING)];
HANDLE shm_handle = NULL; HANDLE shm_handle = NULL, info_handle = NULL;
BOOL created = FALSE; BOOL created = FALSE;
if (key != IPC_PRIVATE) { if (key != IPC_PRIVATE) {

1367
UPGRADING

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
PHP 8.5 INTERNALS UPGRADE NOTES PHP 8.3 INTERNALS UPGRADE NOTES
1. Internal API changes 1. Internal API changes
@ -14,158 +14,157 @@ PHP 8.5 INTERNALS UPGRADE NOTES
1. Internal API changes 1. Internal API changes
======================== ========================
- Core * zend_class_entry now possesses a default_object_handlers field, which
. PG(arg_separator).input and PG(arg_separator).output are now `zend_string*` provides a default object handler when create_object() is not overriding it.
instead of `char*`. * Custom Fiber implementations have to initialize EG(stack_limit) and
. DL_LOAD now doesn't use RTLD_DEEPBIND deepbind anymore on platforms EG(stack_base).
where dlmopen with LM_ID_NEWLM is available: * EG(opline_before_exception) may now be null if the VM throws an exception
this means shared library symbol isolation (if needed) must be enabled on before executing any opline.
the user side when requiring libphp.so, by using dlmopen with LM_ID_NEWLM * Many C header files have been cleaned up and include dependencies
instead of dlopen. have been reduced. Many headers which used to be always included by
RTLD_DEEPBIND is still enabled when the Apache SAPI is in use. Zend headers (e.g. "errno.h") are no longer implied, and this may
. The ptr field of the php_stream_notifier struct is now a void* instead break the build of third-party extensions which relied on this
of a zval. If the zval was used to store IS_PTR values only, the implementation detail. Those extensions may need to add the missing
extra layer of indirection can be removed. In other cases a zval can #include lines.
be heap-allocated and stored in the pointer as a minimal change to keep * Since version 8, PHP requires a C99 compiler. Configure-time checks
compatibility. for C99 features have been removed and therefore macro definitions
from php_config.h have disappeared. Do not use those feature
- Hash macros.
. Hash functions now use proper hash_spec_result enum for return values * Internal class aliases created during request time can now exist in
instead of using SUCCESS and FAILURE. the class table. zend_register_class_alias_ex() will not increase
the refcount for class aliases and the cleanup function takes this
- Zend into account.
. Added zend_safe_assign_to_variable_noref() function to safely assign * The return types of the following functions have been changed from
a value to a non-reference zval. `bool` to `zend_result`:
. Added zval_ptr_safe_dtor() to safely destroy a zval when a destructor - zend_fiber_init_context()
could interfere. * The fast_add_function() has been removed, use add_function() that will
. zend_get_callable_name() now returns the name of the underlying function call the static inline add_function_fast() instead.
for fake closures. * The order of members of zend_op_array, zend_ssa_var, zend_ssa_var_info,
. Added smart_string_append_printf() matching smart_str_append_printf() for zend_executor_globals and php_core_globals have changed to improve
char* instead of zend_string*-based smart strings. struct packing which reduces their size.
. Added php_build_provider() to retrieve the value of PHP_BUILD_PROVIDER at * Many calls to zend_assign_to_variable have been replaced with
runtime. zend_assign_to_variable_ex which allows delaying the releasing of the old
. Removed the cache_slot argument of zend_check_user_type_slow() because variable value. This avoids side-effects through destructors between the
now it only relies on the CE cache. assignment of the variable and the assignment to the result zval in the VM
. Added ZEND_NONSTRING attribute macro for character arrays that do not (i.e. it may free the new value). See GH-10168 for details.
represent strings. This allows to silence the GCC 15.x * The return types of the following functions were changed from int to
`-Wunterminated-string-initialization` warning. zend_result:
. Added the zend_update_exception_properties() function for instantiating - open_file_for_scanning
Exception child classes. It updates the $message, $code, and $previous - php_rfc1867_callback
properties. - virtual_chdir
. zend_exception_get_default() was removed, use zend_ce_exception directly. - zend_execute_scripts
. zend_get_error_exception() was removed, use zend_ce_error_exception - zend_get_module_started
directly. - zend_handle_undef_args
. ZEND_IS_XDIGIT() macro was removed because it was unused and its name - zend_list_delete
did not match its actual behavior. - zend_multibyte_parse_encoding_list
. The following zend_string-related legacy aliases were removed: - zend_multibyte_set_internal_encoding
* IS_INTERNED() - use ZSTR_IS_INTERNED() - zend_parse_ini_file
* STR_EMPTY_ALLOC() - use ZSTR_EMPTY_ALLOC() - zend_parse_ini_string
* _STR_HEADER_SIZE - use _ZSTR_HEADER_SIZE - zend_set_user_opcode_handler
* STR_ALLOCA_ALLOC() - use ZSTR_ALLOCA_ALLOC() - zend_ssa_inference
* STR_ALLOCA_INIT() - use ZSTR_ALLOCA_INIT() * Removed unused macros PHP_FNV1_32A_INIT and PHP_FNV1A_64_INIT. See GH-11114.
* STR_ALLOCA_FREE() - use ZSTR_ALLOCA_FREE() * ext/standard/hrtime.h was moved to Zend/zend_hrtime.h
. zend_register_constant() now returns a pointer to the added constant * The prefix of the PHP_HRTIME_ macros was changed to ZEND_HRTIME_
on success and NULL on failure instead of SUCCESS/FAILURE. * The HRTIME_AVAILABLE macro was renamed to ZEND_HRTIME_AVAILABLE
The specialized registration methods that previously had void returns * The php_hrtime_current() function was renamed to zend_hrtime()
also return pointers to the added constants: * _php_stream_dirent now has an extra d_type field that is used to store the
* zend_register_bool_constant() directory entry type. This can be used to avoid additional stat calls for
* zend_register_null_constant() types when the type is already known.
* zend_register_long_constant() * The misspelled ZEND_CGG_DIAGNOSTIC_IGNORED_(START|END) macros are deprecated.
* zend_register_double_constant() Use ZEND_DIAGNOSTIC_IGNORED_(START|END) instead. These macros now also support
* zend_register_string_constant() Clang.
* 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.
======================== ========================
2. Build system changes 2. Build system changes
======================== ========================
- Abstract * PHP_EXTRA_VERSION can be passed to configure script to control custom PHP
. Preprocessor macro SIZEOF_PTRDIFF_T has been removed. build versions: ./configure PHP_EXTRA_VERSION="-acme"
. Preprocessor macro SIZEOF_INTMAX_T has been removed.
- Windows build system changes * LDFLAGS are not unset anymore allowing them to be adjusted e.g.
. SAPI() and ADD_SOURCES() now support the optional `duplicate_sources` LDFLAGS="..." ./configure
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.
- Unix build system changes * Removed the HAVE_DEV_URANDOM compile time check. HAVE_DEV_URANDOM will
. libdir is properly set when --libdir (ex: /usr/lib64) and --with-libdir (ex: lib64) now never be defined. Any checks relying on HAVE_DEV_URANDOM should be
configure options are used to ${libdir}/php (ex: /usr/lib64/php) removed. Even with HAVE_DEV_URANDOM it was not guaranteed that
. PHP_ODBC_CFLAGS, PHP_ODBC_LFLAGS, PHP_ODBC_LIBS, PHP_ODBC_TYPE preprocessor /dev/urandom is actually available at run time and thus a runtime
macros defined by ext/odbc are now defined in php_config.h instead of the check needs to happen in all cases.
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.
======================== ========================
3. Module changes 3. Module changes
======================== ========================
- ext/gd a. ext/json
. The gdImageScale*() and gdImageRotate*() helpers are now internal in the - A new function php_json_validate_ex has been added to check if the
bundled libgd, like they have been in external libgd as of gd-2.1.1. provided C string is valid for the given depth and options.
- ext/json b. ext/standard
. php_json_encode_serializable_object() now assumes `EG(active)`, - The PHPAPI php_url_encode_hash_ex() function has had its signature change
if not a bailout is caused. Therefore a minor BC break exists if the from:
`PHP_JSON_PARTIAL_OUTPUT_ON_ERROR` option is in use. PHPAPI void php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
However, this situation is highly unlikely. 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 c. ext/mysqlnd
. The refcount APIs now return an `unsigned int` instead of an `int`. - The function mysqlnd_shutdown and its corresponding internal methods
. Removed php_libxml_xmlCheckUTF8(). Use xmlCheckUTF8() from libxml instead. mysqlnd_command::shutdown & mysqlnd_conn_data::shutdown have been removed.
These functions are deprecated by MySQL in favour of SHUTDOWN SQL statement.
- ext/pdo d. ext/pcre
. Added `php_pdo_stmt_valid_db_obj_handle()` to check if the database object - The function pcre_get_compiled_regex_ex has been removed.
is still valid. This is useful when a GC cycle is collected and the Use pcre_get_compiled_regex instead.
database object can be destroyed prior to destroying the statement.
- ext/standard e. ext/spl
. Added php_url_decode_ex() and php_raw_url_decode_ex() that unlike their - The PHPAPI spl_iterator_apply() function now returns zend_result instead of int.
non-ex counterparts do not work in-place. There are no functional changes.
. The php_std_date() function has been removed. Use php_format_date() with - The field _spl_filesystem_object->is_recursive has been removed.
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. f. ext/dom
. The functionality of getimagesize(), image_type_to_mime_type(), - A new function dom_get_doc_props_read_only() is added to gather the document
and image_type_to_extension() is now extensible using the internal APIs properties in a read-only way. This function avoids allocation when there are
php_image_register_handler() and php_image_unregister_handler() in no document properties changed yet.
php_image.h. - 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 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 5. SAPI changes
======================== ========================
- SAPIs must now call php_child_init() after a fork. If php-src code was * SAPIs that may execute in alternative stacks have to set EG(stack_limit) and
executed in other threads than the one initiating the fork, EG(stack_base)
refresh_memory_manager() must be called in every such thread.

View file

@ -6,7 +6,7 @@ $(builddir)/zend_language_scanner.lo: $(srcdir)/zend_language_parser.h
$(builddir)/zend_ini_scanner.lo: $(srcdir)/zend_ini_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 $(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.h: $(srcdir)/zend_language_parser.c
$(srcdir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y $(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.h: $(srcdir)/zend_ini_parser.c
$(srcdir)/zend_ini_parser.c: $(srcdir)/zend_ini_parser.y $(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 $(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 # 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. # at the same time, rather than the same recipe applying for two different targets.

View file

@ -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, * 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. * 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. */ * 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) { if (opline->op1_type == IS_TMP_VAR) {
/* Keep the ZEND_FREE opcode alive. */
} else if (opline->op1_type == IS_TMP_VAR) {
src = VAR_SOURCE(opline->op1); src = VAR_SOURCE(opline->op1);
if (src) { if (src) {
switch (src->opcode) { switch (src->opcode) {
@ -420,14 +418,6 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
} }
break; 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:
case ZEND_CASE_STRICT: case ZEND_CASE_STRICT:
case ZEND_COPY_TMP: case ZEND_COPY_TMP:
@ -478,67 +468,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
goto optimize_bool; goto optimize_bool;
} }
break; 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:
case ZEND_BOOL_NOT: case ZEND_BOOL_NOT:
optimize_bool: optimize_bool:
@ -871,6 +801,7 @@ optimize_type_check:
case ZEND_SR: case ZEND_SR:
case ZEND_IS_SMALLER: case ZEND_IS_SMALLER:
case ZEND_IS_SMALLER_OR_EQUAL: case ZEND_IS_SMALLER_OR_EQUAL:
case ZEND_IS_IDENTICAL:
case ZEND_IS_NOT_IDENTICAL: case ZEND_IS_NOT_IDENTICAL:
case ZEND_BOOL_XOR: case ZEND_BOOL_XOR:
case ZEND_BW_OR: case ZEND_BW_OR:
@ -937,6 +868,7 @@ optimize_const_unary_op:
break; break;
case ZEND_RETURN: case ZEND_RETURN:
case ZEND_EXIT:
if (opline->op1_type == IS_TMP_VAR) { if (opline->op1_type == IS_TMP_VAR) {
src = VAR_SOURCE(opline->op1); src = VAR_SOURCE(opline->op1);
if (src && src->opcode == ZEND_QM_ASSIGN) { 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_ASSERT_CHECK:
case ZEND_JMP_NULL: case ZEND_JMP_NULL:
case ZEND_BIND_INIT_STATIC_OR_JMP: 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); ZEND_SET_OP_JMP_ADDR(opline, opline->op2, new_opcodes + blocks[b->successors[0]].start);
break; break;
case ZEND_CATCH: 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; target = op_array->opcodes + target_block->start;
if ((target->opcode == ZEND_RETURN || if ((target->opcode == ZEND_RETURN ||
target->opcode == ZEND_RETURN_BY_REF || 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)) { !(op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) {
/* JMP L, L: RETURN to immediate RETURN */ /* JMP L, L: RETURN to immediate RETURN */
*last_op = *target; *last_op = *target;

View file

@ -43,6 +43,50 @@ typedef struct _literal_info {
info[n].num_related = (related); \ info[n].num_related = (related); \
} while (0) } 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, static uint32_t add_static_slot(HashTable *hash,
zend_op_array *op_array, zend_op_array *op_array,
uint32_t op1, uint32_t op1,
@ -121,7 +165,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
HashTable hash; HashTable hash;
zend_string *key = NULL; zend_string *key = NULL;
void *checkpoint = zend_arena_checkpoint(ctx->arena); 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) { if (op_array->last_literal) {
info = (literal_info*)zend_arena_calloc(&ctx->arena, op_array->last_literal, sizeof(literal_info)); 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; end = opline + op_array->last;
while (opline < end) { while (opline < end) {
switch (opline->opcode) { switch (opline->opcode) {
case ZEND_JMP_FRAMELESS:
LITERAL_INFO(opline->op1.constant, 1);
break;
case ZEND_INIT_FCALL_BY_NAME: case ZEND_INIT_FCALL_BY_NAME:
LITERAL_INFO(opline->op2.constant, 2); LITERAL_INFO(opline->op2.constant, 2);
break; break;
@ -156,9 +197,6 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
LITERAL_INFO(opline->op2.constant, 2); LITERAL_INFO(opline->op2.constant, 2);
} }
break; break;
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:
LITERAL_INFO(opline->op1.constant, 1);
break;
case ZEND_CATCH: case ZEND_CATCH:
LITERAL_INFO(opline->op1.constant, 2); LITERAL_INFO(opline->op1.constant, 2);
break; break;
@ -439,14 +477,13 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
zend_hash_clean(&hash); zend_hash_clean(&hash);
op_array->last_literal = j; op_array->last_literal = j;
const_slot = zend_arena_alloc(&ctx->arena, j * 7 * sizeof(int)); const_slot = zend_arena_alloc(&ctx->arena, j * 6 * sizeof(int));
memset(const_slot, -1, j * 7 * sizeof(int)); memset(const_slot, -1, j * 6 * sizeof(int));
class_slot = const_slot + j; class_slot = const_slot + j;
func_slot = class_slot + j; func_slot = class_slot + j;
bind_var_slot = func_slot + j; bind_var_slot = func_slot + j;
property_slot = bind_var_slot + j; property_slot = bind_var_slot + j;
method_slot = property_slot + j; method_slot = property_slot + j;
jmp_slot = method_slot + j;
/* Update opcodes to use new literals table */ /* Update opcodes to use new literals table */
cache_size = zend_op_array_extension_handles * sizeof(void*); 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]; opline->op2.constant = map[opline->op2.constant];
} }
switch (opline->opcode) { 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: case ZEND_ASSIGN_STATIC_PROP_OP:
if (opline->op1_type == IS_CONST) { if (opline->op1_type == IS_CONST) {
// op1 static property // 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; opline->extended_value = cache_size;
cache_size += sizeof(void *); cache_size += sizeof(void *);
break; 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:
case ZEND_SEND_VAL_EX: case ZEND_SEND_VAL_EX:
case ZEND_SEND_VAR: case ZEND_SEND_VAR:

View file

@ -80,6 +80,7 @@ static inline bool may_have_side_effects(
case ZEND_IS_IDENTICAL: case ZEND_IS_IDENTICAL:
case ZEND_IS_NOT_IDENTICAL: case ZEND_IS_NOT_IDENTICAL:
case ZEND_QM_ASSIGN: case ZEND_QM_ASSIGN:
case ZEND_FREE:
case ZEND_FE_FREE: case ZEND_FE_FREE:
case ZEND_TYPE_CHECK: case ZEND_TYPE_CHECK:
case ZEND_DEFINED: case ZEND_DEFINED:
@ -126,8 +127,6 @@ static inline bool may_have_side_effects(
case ZEND_ARRAY_KEY_EXISTS: case ZEND_ARRAY_KEY_EXISTS:
/* No side effects */ /* No side effects */
return 0; return 0;
case ZEND_FREE:
return opline->extended_value == ZEND_FREE_VOID_CAST;
case ZEND_ADD_ARRAY_ELEMENT: case ZEND_ADD_ARRAY_ELEMENT:
/* TODO: We can't free two vars. Keep instruction alive. <?php [0, "$a" => "$b"]; */ /* 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))) { 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_ASSERT_CHECK:
case ZEND_JMP_NULL: case ZEND_JMP_NULL:
case ZEND_BIND_INIT_STATIC_OR_JMP: case ZEND_BIND_INIT_STATIC_OR_JMP:
case ZEND_JMP_FRAMELESS:
/* For our purposes a jumps and branches are side effects. */ /* For our purposes a jumps and branches are side effects. */
return 1; return 1;
case ZEND_BEGIN_SILENCE: case ZEND_BEGIN_SILENCE:
@ -169,10 +167,6 @@ static inline bool may_have_side_effects(
case ZEND_DO_FCALL_BY_NAME: case ZEND_DO_FCALL_BY_NAME:
case ZEND_DO_ICALL: case ZEND_DO_ICALL:
case ZEND_DO_UCALL: 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 */ /* For now assume all calls have side effects */
return 1; return 1;
case ZEND_RECV: case ZEND_RECV:

View file

@ -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); 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) { if (ce1 == ce2) {
return 1; 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( static inline bool can_elide_list_type(
const zend_script *script, const zend_op_array *op_array, 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 intersection: result==false is failure, default is success.
* For union: result==true is success, default is failure. */ * For union: result==true is success, default is failure. */
bool is_intersection = ZEND_TYPE_IS_INTERSECTION(type); 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)) { if (ZEND_TYPE_HAS_NAME(*single_type)) {
zend_string *lcname = zend_string_tolower(ZEND_TYPE_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); zend_string_release(lcname);
bool result = ce && safe_instanceof(use_info->ce, ce); bool result = ce && safe_instanceof(use_info->ce, ce);
if (result == !is_intersection) { if (result == !is_intersection) {
@ -325,19 +325,6 @@ static bool opline_supports_assign_contraction(
return 0; 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 if (opline->opcode == ZEND_DO_ICALL || opline->opcode == ZEND_DO_UCALL
|| opline->opcode == ZEND_DO_FCALL || opline->opcode == ZEND_DO_FCALL_BY_NAME) { || 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 /* 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; zend_call_info *call_info = func_info->callee_info;
do { do {
zend_op *op = call_info->caller_init_opline; if (call_info->caller_call_opline
&& call_info->caller_call_opline->opcode == ZEND_DO_ICALL
if ((op->opcode == ZEND_FRAMELESS_ICALL_2
|| (op->opcode == ZEND_FRAMELESS_ICALL_3 && (op + 1)->op1_type == IS_CONST))
&& call_info->callee_func && 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 strict = 0;
bool has_opdata = op->opcode == ZEND_FRAMELESS_ICALL_3;
ZEND_ASSERT(!call_info->is_prototype); ZEND_ASSERT(!call_info->is_prototype);
if (has_opdata) { if (call_info->caller_init_opline->extended_value == 2) {
if (zend_is_true(CT_CONSTANT_EX(op_array, (op + 1)->op1.constant))) { 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; strict = 1;
} }
send_array = call_info->caller_call_opline - 2;
send_needly = call_info->caller_call_opline - 3;
} }
if (op->op2_type == IS_CONST if (send_array->opcode == ZEND_SEND_VAL
&& Z_TYPE_P(CT_CONSTANT_EX(op_array, op->op2.constant)) == IS_ARRAY) { && 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; 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; HashTable *dst;
zval *val, tmp; zval *val, tmp;
zend_ulong idx; zend_ulong idx;
@ -459,15 +458,59 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa)
} }
if (ok) { 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); ZVAL_ARR(&tmp, dst);
/* Update opcode */ /* Update opcode */
op->opcode = ZEND_IN_ARRAY; call_info->caller_call_opline->opcode = ZEND_IN_ARRAY;
op->extended_value = strict; call_info->caller_call_opline->extended_value = strict;
op->op2.constant = zend_optimizer_add_literal(op_array, &tmp); call_info->caller_call_opline->op1_type = send_needly->op1_type;
if (has_opdata) { call_info->caller_call_opline->op1.num = send_needly->op1.num;
MAKE_NOP(op + 1); call_info->caller_call_opline->op2_type = IS_CONST;
removed_ops++; 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_ASSERT_CHECK:
case ZEND_JMP_NULL: case ZEND_JMP_NULL:
case ZEND_BIND_INIT_STATIC_OR_JMP: case ZEND_BIND_INIT_STATIC_OR_JMP:
case ZEND_JMP_FRAMELESS:
if (ZEND_OP2_JMP_ADDR(opline) == op_array->opcodes + old->start) { if (ZEND_OP2_JMP_ADDR(opline) == op_array->opcodes + old->start) {
ZEND_SET_OP_JMP_ADDR(opline, opline->op2, op_array->opcodes + dst->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) 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; 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 if (result_var >= 0
&& !(ssa->var_info[cv_var].type & MAY_BE_REF) && !(ssa->var_info[cv_var].type & MAY_BE_REF)

View file

@ -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_STATIC_METHOD_CALL:
case ZEND_INIT_METHOD_CALL: case ZEND_INIT_METHOD_CALL:
case ZEND_INIT_FCALL: case ZEND_INIT_FCALL:
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:
if (call == 0) { if (call == 0) {
MAKE_NOP(opline); MAKE_NOP(opline);
return; 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) 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 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 ??? */ /* TODO: function copied from trait may be inconsistent ??? */
&& !(func->op_array.fn_flags & (ZEND_ACC_TRAIT_CLONE)) && !(func->op_array.fn_flags & (ZEND_ACC_TRAIT_CLONE))
&& fcall->extended_value >= func->op_array.required_num_args && 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_METHOD_CALL:
case ZEND_INIT_FCALL: case ZEND_INIT_FCALL:
case ZEND_NEW: case ZEND_NEW:
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:
/* The argument passing optimizations are valid for prototypes as well, /* The argument passing optimizations are valid for prototypes as well,
* as inheritance cannot change between ref <-> non-ref arguments. */ * as inheritance cannot change between ref <-> non-ref arguments. */
call_stack[call].func = zend_optimizer_get_called_func( call_stack[call].func = zend_optimizer_get_called_func(
ctx->script, op_array, opline, &call_stack[call].is_prototype); ctx->script, op_array, opline, &call_stack[call].is_prototype);
call_stack[call].try_inline = call_stack[call].try_inline =
!call_stack[call].is_prototype !call_stack[call].is_prototype && opline->opcode != ZEND_NEW;
&& opline->opcode != ZEND_NEW
&& opline->opcode != ZEND_INIT_PARENT_PROPERTY_HOOK_CALL;
ZEND_FALLTHROUGH; ZEND_FALLTHROUGH;
case ZEND_INIT_DYNAMIC_CALL: case ZEND_INIT_DYNAMIC_CALL:
case ZEND_INIT_USER_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); fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func);
literal_dtor(&ZEND_OP2_LITERAL(fcall)); literal_dtor(&ZEND_OP2_LITERAL(fcall));
fcall->op2.constant = fcall->op2.constant + 1; 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) { } else if (fcall->opcode == ZEND_INIT_NS_FCALL_BY_NAME) {
fcall->opcode = ZEND_INIT_FCALL; fcall->opcode = ZEND_INIT_FCALL;
fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func); 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]);
literal_dtor(&op_array->literals[fcall->op2.constant + 2]); literal_dtor(&op_array->literals[fcall->op2.constant + 2]);
fcall->op2.constant = fcall->op2.constant + 1; 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 } else if (fcall->opcode == ZEND_INIT_STATIC_METHOD_CALL
|| fcall->opcode == ZEND_INIT_METHOD_CALL || fcall->opcode == ZEND_INIT_METHOD_CALL
|| fcall->opcode == ZEND_INIT_PARENT_PROPERTY_HOOK_CALL
|| fcall->opcode == ZEND_NEW) { || fcall->opcode == ZEND_NEW) {
/* We don't have specialized opcodes for this, do nothing */ /* We don't have specialized opcodes for this, do nothing */
} else { } else {
ZEND_UNREACHABLE(); 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) if ((ZEND_OPTIMIZER_PASS_16 & ctx->optimization_level)
&& call_stack[call].try_inline && call_stack[call].try_inline
&& opline->opcode != ZEND_CALLABLE_CONVERT) { && opline->opcode != ZEND_CALLABLE_CONVERT) {

View file

@ -161,26 +161,33 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
} }
break; break;
case ZEND_FETCH_CLASS_CONSTANT: { case ZEND_FETCH_CLASS_CONSTANT:
bool is_prototype; if (opline->op2_type == IS_CONST &&
const zend_class_constant *cc = zend_fetch_class_const_info(ctx->script, op_array, opline, &is_prototype); Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) {
if (!cc || is_prototype) {
break; zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1(
} ctx->script, op_array, opline);
const zval *c = &cc->value; if (ce) {
if (Z_TYPE_P(c) == IS_CONSTANT_AST) { zend_class_constant *cc = zend_hash_find_ptr(
zend_ast *ast = Z_ASTVAL_P(c); &ce->constants_table, Z_STR(ZEND_OP2_LITERAL(opline)));
if (ast->kind != ZEND_AST_CONSTANT 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)) {
|| !zend_optimizer_get_persistent_constant(zend_ast_get_constant_name(ast), &result, 1) zval *c = &cc->value;
|| Z_TYPE(result) == IS_CONSTANT_AST) { if (Z_TYPE_P(c) == IS_CONSTANT_AST) {
break; zend_ast *ast = Z_ASTVAL_P(c);
if (ast->kind != ZEND_AST_CONSTANT
|| !zend_optimizer_get_persistent_constant(zend_ast_get_constant_name(ast), &result, 1)
|| Z_TYPE(result) == IS_CONSTANT_AST) {
break;
}
} else {
ZVAL_COPY_OR_DUP(&result, c);
}
replace_by_const_or_qm_assign(op_array, opline, &result);
}
} }
} else {
ZVAL_COPY_OR_DUP(&result, c);
} }
replace_by_const_or_qm_assign(op_array, opline, &result);
break; break;
}
case ZEND_DO_ICALL: { case ZEND_DO_ICALL: {
zend_op *send1_opline = opline - 1; 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_JMPZ:
case ZEND_JMPNZ: case ZEND_JMPNZ:
if (opline->op1_type == IS_CONST) { 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) { if (opline->opcode == ZEND_JMPZ) {
should_jmp = !should_jmp; 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:
case ZEND_RETURN_BY_REF: case ZEND_RETURN_BY_REF:
case ZEND_GENERATOR_RETURN: case ZEND_GENERATOR_RETURN:
case ZEND_EXIT:
case ZEND_THROW: case ZEND_THROW:
case ZEND_MATCH_ERROR: case ZEND_MATCH_ERROR:
case ZEND_CATCH: 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_JMP_NULL:
case ZEND_VERIFY_NEVER_TYPE: case ZEND_VERIFY_NEVER_TYPE:
case ZEND_BIND_INIT_STATIC_OR_JMP: case ZEND_BIND_INIT_STATIC_OR_JMP:
case ZEND_JMP_FRAMELESS:
collect_constants = 0; collect_constants = 0;
break; break;
} }

View file

@ -88,7 +88,8 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx)
MAKE_NOP(opline); MAKE_NOP(opline);
} else if ((target->opcode == ZEND_RETURN || } else if ((target->opcode == ZEND_RETURN ||
target->opcode == ZEND_RETURN_BY_REF || 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)) { !(op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) {
/* JMP L, L: RETURN to immediate RETURN */ /* JMP L, L: RETURN to immediate RETURN */
*opline = *target; *opline = *target;

View file

@ -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, /* 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 * or just happened to be commonly used with constant operands in WP (need to test other
* applications as well, of course). */ * applications as well, of course). */
static inline zend_result ct_eval_func_call_ex( static inline zend_result ct_eval_func_call(
zend_op_array *op_array, zval *result, zend_function *func, uint32_t num_args, zval **args) { zend_op_array *op_array, zval *result, zend_string *name, uint32_t num_args, zval **args) {
uint32_t i; 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 && 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) { zend_optimizer_eval_special_func_call(result, name, Z_STR_P(args[0])) == SUCCESS) {
return SUCCESS; return SUCCESS;
@ -851,15 +855,6 @@ static inline zend_result ct_eval_func_call_ex(
return retval; 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 { \ #define SET_RESULT(op, zv) do { \
if (ssa_op->op##_def >= 0) { \ if (ssa_op->op##_def >= 0) { \
set_value(scdf, ctx, ssa_op->op##_def, zv); \ 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); SET_RESULT_BOT(result);
break; 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: default:
{ {
/* If we have no explicit implementation return BOT */ /* 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) { if (opline->opcode == ZEND_DO_ICALL) {
removed_ops = remove_call(ctx, opline, ssa_op) - 1; removed_ops = remove_call(ctx, opline, ssa_op) - 1;
} else { } else {
bool has_op_data = opline->opcode == ZEND_FRAMELESS_ICALL_3;
zend_ssa_remove_instr(ssa, opline, ssa_op); 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; ssa_op->result_def = var_num;
opline->opcode = ZEND_QM_ASSIGN; 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) { if (opline->opcode == ZEND_DO_ICALL) {
removed_ops = remove_call(ctx, opline, ssa_op); removed_ops = remove_call(ctx, opline, ssa_op);
} else { } else {
bool has_op_data = opline->opcode == ZEND_FRAMELESS_ICALL_3;
zend_ssa_remove_instr(ssa, opline, ssa_op); zend_ssa_remove_instr(ssa, opline, ssa_op);
removed_ops++; 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) { } else if (ssa_op->op1_def == var_num) {

View file

@ -61,7 +61,6 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32
case ZEND_INIT_FCALL: case ZEND_INIT_FCALL:
case ZEND_INIT_METHOD_CALL: case ZEND_INIT_METHOD_CALL:
case ZEND_INIT_STATIC_METHOD_CALL: case ZEND_INIT_STATIC_METHOD_CALL:
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:
call_stack[call] = call_info; call_stack[call] = call_info;
func = zend_optimizer_get_called_func( func = zend_optimizer_get_called_func(
script, op_array, opline, &is_prototype); 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->num_args = opline->extended_value;
call_info->next_callee = func_info->callee_info; call_info->next_callee = func_info->callee_info;
call_info->is_prototype = is_prototype; call_info->is_prototype = is_prototype;
call_info->is_frameless = false;
func_info->callee_info = call_info; func_info->callee_info = call_info;
if (build_flags & ZEND_CALL_TREE) { if (build_flags & ZEND_CALL_TREE) {
call_info->next_caller = NULL; call_info->next_caller = NULL;
} else if (func->type == ZEND_INTERNAL_FUNCTION } else if (func->type == ZEND_INTERNAL_FUNCTION) {
|| func->op_array.filename != script->filename) {
call_info->next_caller = NULL; call_info->next_caller = NULL;
} else { } else {
zend_func_info *callee_func_info = ZEND_FUNC_INFO(&func->op_array); 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_info = NULL;
call++; call++;
break; 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_FCALL:
case ZEND_DO_ICALL: case ZEND_DO_ICALL:
case ZEND_DO_UCALL: 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; call_info->send_unpack = 1;
} }
break; break;
case ZEND_EXIT:
/* In this case the DO_CALL opcode may have been dropped
* and caller_call_opline will be NULL. */
break;
} }
opline++; opline++;
} }
@ -277,11 +260,9 @@ ZEND_API zend_call_info **zend_build_call_map(zend_arena **arena, zend_func_info
if (call->caller_call_opline) { if (call->caller_call_opline) {
map[call->caller_call_opline - op_array->opcodes] = call; map[call->caller_call_opline - op_array->opcodes] = call;
} }
if (!call->is_frameless) { for (i = 0; i < call->num_args; i++) {
for (i = 0; i < call->num_args; i++) { if (call->arg_info[i].opline) {
if (call->arg_info[i].opline) { map[call->arg_info[i].opline - op_array->opcodes] = call;
map[call->arg_info[i].opline - op_array->opcodes] = call;
}
} }
} }
} }

View file

@ -38,7 +38,6 @@ struct _zend_call_info {
bool send_unpack; /* Parameters passed by SEND_UNPACK or SEND_ARRAY */ bool send_unpack; /* Parameters passed by SEND_UNPACK or SEND_ARRAY */
bool named_args; /* Function has named arguments */ bool named_args; /* Function has named arguments */
bool is_prototype; /* An overridden child method may be called */ 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 */ int num_args; /* Number of arguments, excluding named and variadic arguments */
zend_send_arg_info arg_info[1]; zend_send_arg_info arg_info[1];
}; };

View file

@ -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_basic_block *blocks = cfg->blocks;
zend_worklist work; while (1) {
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)) {
int i; int i;
b = cfg->blocks + zend_worklist_pop(&work);
b->flags |= ZEND_BB_REACHABLE; b->flags |= ZEND_BB_REACHABLE;
if (b->successors_count == 0) { if (b->successors_count == 0) {
b->flags |= ZEND_BB_EXIT; b->flags |= ZEND_BB_EXIT;
continue; return;
} }
for (i = 0; i < b->successors_count; i++) { 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; succ->flags |= ZEND_BB_FOLLOW;
} }
/* Check reachability of successor */ if (i == b->successors_count - 1) {
if (!(succ->flags & ZEND_BB_REACHABLE)) { /* Tail call optimization */
zend_worklist_push(&work, succ - cfg->blocks); if (succ->flags & ZEND_BB_REACHABLE) {
return;
}
b = succ;
break;
} else {
/* Recursively check reachability */
if (!(succ->flags & ZEND_BB_REACHABLE)) {
zend_mark_reachable(opcodes, cfg, succ);
}
} }
} }
} }
ZEND_WORKLIST_FREE_ALLOCA(&work, list_use_heap);
} }
/* }}} */ /* }}} */
@ -306,6 +307,7 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array,
} }
break; break;
case ZEND_MATCH_ERROR: case ZEND_MATCH_ERROR:
case ZEND_EXIT:
case ZEND_THROW: case ZEND_THROW:
/* Don't treat THROW as terminator if it's used in expression context, /* Don't treat THROW as terminator if it's used in expression context,
* as we may lose live ranges when eliminating unreachable code. */ * 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_ASSERT_CHECK:
case ZEND_JMP_NULL: case ZEND_JMP_NULL:
case ZEND_BIND_INIT_STATIC_OR_JMP: case ZEND_BIND_INIT_STATIC_OR_JMP:
case ZEND_JMP_FRAMELESS:
BB_START(OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes); BB_START(OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes);
BB_START(i + 1); BB_START(i + 1);
break; 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:
case ZEND_RETURN_BY_REF: case ZEND_RETURN_BY_REF:
case ZEND_GENERATOR_RETURN: case ZEND_GENERATOR_RETURN:
case ZEND_EXIT:
case ZEND_THROW: case ZEND_THROW:
case ZEND_MATCH_ERROR: case ZEND_MATCH_ERROR:
case ZEND_VERIFY_NEVER_TYPE: 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_ASSERT_CHECK:
case ZEND_JMP_NULL: case ZEND_JMP_NULL:
case ZEND_BIND_INIT_STATIC_OR_JMP: case ZEND_BIND_INIT_STATIC_OR_JMP:
case ZEND_JMP_FRAMELESS:
block->successors_count = 2; block->successors_count = 2;
block->successors[0] = block_map[OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes]; block->successors[0] = block_map[OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes];
block->successors[1] = j + 1; block->successors[1] = j + 1;

View file

@ -122,7 +122,6 @@ add_op1_def:
} }
break; break;
case ZEND_ASSIGN_STATIC_PROP_OP: case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_FRAMELESS_ICALL_3:
next = opline + 1; next = opline + 1;
if (next->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) { if (next->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
var_num = EX_VAR_TO_NUM(next->op1.var); var_num = EX_VAR_TO_NUM(next->op1.var);

View file

@ -23,7 +23,7 @@
#include "zend_func_info.h" #include "zend_func_info.h"
#include "zend_call_graph.h" #include "zend_call_graph.h"
#include "zend_dump.h" #include "zend_dump.h"
#include "zend_smart_str.h" #include "ext/standard/php_string.h"
void zend_dump_ht(HashTable *ht) void zend_dump_ht(HashTable *ht)
{ {
@ -66,27 +66,13 @@ void zend_dump_const(const zval *zv)
case IS_DOUBLE: case IS_DOUBLE:
fprintf(stderr, " float(%g)", Z_DVAL_P(zv)); fprintf(stderr, " float(%g)", Z_DVAL_P(zv));
break; break;
case IS_STRING: { case IS_STRING:;
smart_str escaped_string = {0}; zend_string *escaped_string = php_addcslashes(Z_STR_P(zv), "\"\\", 2);
smart_str_append_escaped(&escaped_string, Z_STRVAL_P(zv), Z_STRLEN_P(zv));
smart_str_0(&escaped_string);
fprintf(stderr, " string(\""); fprintf(stderr, " string(\"%s\")", ZSTR_VAL(escaped_string));
/* Also escape '"' */ zend_string_release(escaped_string);
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);
break; break;
}
case IS_ARRAY: case IS_ARRAY:
fprintf(stderr, " array(...)"); fprintf(stderr, " array(...)");
break; 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) { if (var_type == IS_CV && var_num < op_array->last_var) {
fprintf(stderr, "CV%d($%s)", var_num, op_array->vars[var_num]->val); 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); 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) { if (ssa_var_num >= 0) {
fprintf(stderr, "#%d.", ssa_var_num); 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); 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)) { if (ZEND_VM_EXT_NUM == (flags & ZEND_VM_EXT_MASK)) {
fprintf(stderr, " %u", opline->extended_value); fprintf(stderr, " %u", opline->extended_value);
} else if (ZEND_VM_EXT_OP == (flags & ZEND_VM_EXT_MASK)) { } 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) 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_cfg *cfg = NULL;
const zend_ssa *ssa = NULL; const zend_ssa *ssa = NULL;
zend_func_info *func_info = 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) { 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, " ; "); fprintf(stderr, " ; ");
zend_dump_ssa_var(op_array, ssa, i, IS_CV, i, dump_flags); zend_dump_ssa_var(op_array, ssa, i, IS_CV, i, dump_flags);
fprintf(stderr, "\n"); 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)) { if (op_array->last_live_range && (dump_flags & ZEND_DUMP_LIVE_RANGES)) {
fprintf(stderr, "LIVE RANGES:\n"); 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, fprintf(stderr,
" %u: %04u - %04u ", " %u: %04u - %04u ",
EX_VAR_TO_NUM(op_array->live_range[i].var & ~ZEND_LIVE_MASK), 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) { if (op_array->last_try_catch) {
fprintf(stderr, "EXCEPTION TABLE:\n"); 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", fprintf(stderr, " BB%u",
cfg->map[op_array->try_catch_array[i].try_op]); cfg->map[op_array->try_catch_array[i].try_op]);
if (op_array->try_catch_array[i].catch_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)) { if (op_array->last_live_range && (dump_flags & ZEND_DUMP_LIVE_RANGES)) {
fprintf(stderr, "LIVE RANGES:\n"); 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, fprintf(stderr,
" %u: %04u - %04u ", " %u: %04u - %04u ",
EX_VAR_TO_NUM(op_array->live_range[i].var & ~ZEND_LIVE_MASK), 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) { if (op_array->last_try_catch) {
fprintf(stderr, "EXCEPTION TABLE:\n"); 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, fprintf(stderr,
" %04u", " %04u",
op_array->try_catch_array[i].try_op); 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) void zend_dump_ssa_variables(const zend_op_array *op_array, const zend_ssa *ssa, uint32_t dump_flags)
{ {
int j; int j;

View file

@ -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_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_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_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); 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_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, uint32_t var_num); 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_op_array_name(const zend_op_array *op_array);
void zend_dump_const(const zval *zv); void zend_dump_const(const zval *zv);
void zend_dump_ht(HashTable *ht); void zend_dump_ht(HashTable *ht);

View file

@ -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) 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 if (!call_info->send_unpack
&& (call_info->num_args == 2 || call_info->num_args == 3) && (call_info->num_args == 2 || call_info->num_args == 3)
&& ssa && ssa
&& !(ssa->cfg.flags & ZEND_SSA_TSSA)) { && !(ssa->cfg.flags & ZEND_SSA_TSSA)) {
zend_op_array *op_array = call_info->caller_op_array; 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, 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, 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 t3 = 0;
uint32_t tmp = MAY_BE_RC1 | MAY_BE_ARRAY; uint32_t tmp = MAY_BE_RC1 | MAY_BE_ARRAY;
if (call_info->num_args == 3) { if (call_info->num_args == 3) {
t3 = _ssa_op1_info(op_array, ssa, call_info->arg_info[2].opline, 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)) { 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; tmp |= MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_DOUBLE | MAY_BE_ARRAY_OF_STRING;

View file

@ -1,7 +1,6 @@
/* This is a generated file, edit the .stub.php files instead. */ /* This is a generated file, edit the .stub.php files instead. */
static const func_info_t func_infos[] = { static const func_info_t func_infos[] = {
F1("clone", MAY_BE_OBJECT),
F1("zend_version", MAY_BE_STRING), F1("zend_version", MAY_BE_STRING),
FN("func_get_args", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_ANY), 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), 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("bcmul", MAY_BE_STRING),
F1("bcdiv", MAY_BE_STRING), F1("bcdiv", MAY_BE_STRING),
F1("bcmod", 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("bcpowmod", MAY_BE_STRING),
F1("bcpow", MAY_BE_STRING), F1("bcpow", MAY_BE_STRING),
F1("bcsqrt", 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), 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("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), 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_multi_strerror", MAY_BE_STRING|MAY_BE_NULL),
F1("curl_share_init", MAY_BE_OBJECT), F1("curl_share_init", MAY_BE_OBJECT),
F1("curl_share_strerror", MAY_BE_STRING|MAY_BE_NULL), 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_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("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), 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_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_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), 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), 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), 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), 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), F1("imagecreatetruecolor", MAY_BE_OBJECT|MAY_BE_FALSE),
#if defined(PHP_WIN32) #if defined(PHP_WIN32)
F1("imagegrabwindow", MAY_BE_OBJECT|MAY_BE_FALSE), F1("imagegrabwindow", MAY_BE_OBJECT|MAY_BE_FALSE),
#endif
#if defined(PHP_WIN32)
F1("imagegrabscreen", MAY_BE_OBJECT|MAY_BE_FALSE), F1("imagegrabscreen", MAY_BE_OBJECT|MAY_BE_FALSE),
#endif #endif
F1("imagerotate", MAY_BE_OBJECT|MAY_BE_FALSE), 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("imagecreatefromgd", MAY_BE_OBJECT|MAY_BE_FALSE),
F1("imagecreatefromgd2", MAY_BE_OBJECT|MAY_BE_FALSE), F1("imagecreatefromgd2", MAY_BE_OBJECT|MAY_BE_FALSE),
F1("imagecreatefromgd2part", 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), 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("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), F1("imagegetclip", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_LONG),
#if defined(HAVE_GD_FREETYPE) #if defined(HAVE_GD_FREETYPE)
F1("imageftbbox", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_LONG|MAY_BE_FALSE), 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), F1("imagefttext", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_LONG|MAY_BE_FALSE),
#endif #endif
F1("imagecrop", MAY_BE_OBJECT|MAY_BE_FALSE), 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), F1("hash_hkdf", MAY_BE_STRING),
#if defined(PHP_MHASH_BC) #if defined(PHP_MHASH_BC)
F1("mhash_get_hash_name", MAY_BE_STRING|MAY_BE_FALSE), 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), F1("mhash_keygen_s2k", MAY_BE_STRING|MAY_BE_FALSE),
#endif
#if defined(PHP_MHASH_BC)
F1("mhash", MAY_BE_STRING|MAY_BE_FALSE), F1("mhash", MAY_BE_STRING|MAY_BE_FALSE),
#endif #endif
F1("iconv_substr", MAY_BE_STRING|MAY_BE_FALSE), 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), 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) #if defined(HAVE_MBREGEX)
F1("mb_regex_encoding", MAY_BE_STRING|MAY_BE_BOOL), 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), 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), 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), 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), 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), 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), 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), 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), F1("mb_regex_set_options", MAY_BE_STRING),
#endif #endif
F1("mysqli_affected_rows", MAY_BE_LONG|MAY_BE_STRING), 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_stat", MAY_BE_STRING|MAY_BE_FALSE),
F1("mysqli_store_result", MAY_BE_OBJECT|MAY_BE_FALSE), F1("mysqli_store_result", MAY_BE_OBJECT|MAY_BE_FALSE),
F1("mysqli_use_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_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("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), 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_tty", MAY_BE_STRING),
F1("pg_host", 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_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_parameter_status", MAY_BE_STRING|MAY_BE_FALSE),
F1("pg_query", MAY_BE_OBJECT|MAY_BE_FALSE), F1("pg_query", MAY_BE_OBJECT|MAY_BE_FALSE),
F1("pg_query_params", 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) #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), 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 #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), F1("random_bytes", MAY_BE_STRING),
#if defined(HAVE_HISTORY_LIST) #if defined(HAVE_HISTORY_LIST)
F1("readline_list_history", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING), 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), 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) #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), 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), 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 #endif
F1("class_implements", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE), 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), 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_encode", MAY_BE_STRING),
F1("base64_decode", MAY_BE_STRING|MAY_BE_FALSE), 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("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), 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) #if defined(HAVE_NANOSLEEP)
@ -421,13 +478,14 @@ static const func_info_t func_infos[] = {
#endif #endif
F1("get_current_user", MAY_BE_STRING), 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), 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("highlight_file", MAY_BE_STRING|MAY_BE_BOOL),
F1("php_strip_whitespace", MAY_BE_STRING), 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("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("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) #if defined(HAVE_GETSERVBYPORT)
F1("getservbyport", MAY_BE_STRING|MAY_BE_FALSE), F1("getservbyport", MAY_BE_STRING|MAY_BE_FALSE),
#endif #endif
@ -460,8 +518,12 @@ static const func_info_t func_infos[] = {
F1("md5_file", MAY_BE_STRING|MAY_BE_FALSE), F1("md5_file", MAY_BE_STRING|MAY_BE_FALSE),
F1("sha1", MAY_BE_STRING), F1("sha1", MAY_BE_STRING),
F1("sha1_file", MAY_BE_STRING|MAY_BE_FALSE), F1("sha1_file", MAY_BE_STRING|MAY_BE_FALSE),
#if defined(HAVE_INET_NTOP)
F1("inet_ntop", MAY_BE_STRING|MAY_BE_FALSE), F1("inet_ntop", MAY_BE_STRING|MAY_BE_FALSE),
#endif
#if defined(HAVE_INET_PTON)
F1("inet_pton", MAY_BE_STRING|MAY_BE_FALSE), F1("inet_pton", MAY_BE_STRING|MAY_BE_FALSE),
#endif
F1("metaphone", MAY_BE_STRING), F1("metaphone", MAY_BE_STRING),
F1("headers_list", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING), F1("headers_list", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
F1("htmlspecialchars", MAY_BE_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("getcwd", MAY_BE_STRING|MAY_BE_FALSE),
F1("readdir", 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), 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), 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("exec", MAY_BE_STRING|MAY_BE_FALSE),
F1("system", MAY_BE_STRING|MAY_BE_FALSE), F1("system", MAY_BE_STRING|MAY_BE_FALSE),
F1("escapeshellcmd", MAY_BE_STRING), F1("escapeshellcmd", MAY_BE_STRING),
@ -539,7 +603,6 @@ static const func_info_t func_infos[] = {
F1("fsockopen", MAY_BE_RESOURCE|MAY_BE_FALSE), F1("fsockopen", MAY_BE_RESOURCE|MAY_BE_FALSE),
FN("pfsockopen", MAY_BE_RESOURCE|MAY_BE_FALSE), FN("pfsockopen", MAY_BE_RESOURCE|MAY_BE_FALSE),
F1("http_build_query", MAY_BE_STRING), 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_mime_type", MAY_BE_STRING),
F1("image_type_to_extension", MAY_BE_STRING|MAY_BE_FALSE), 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), 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), F1("number_format", MAY_BE_STRING),
#if defined(HAVE_GETTIMEOFDAY) #if defined(HAVE_GETTIMEOFDAY)
F1("microtime", MAY_BE_STRING|MAY_BE_DOUBLE), 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), F1("gettimeofday", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_DOUBLE),
#endif #endif
#if defined(HAVE_GETRUSAGE) #if defined(HAVE_GETRUSAGE)
@ -572,6 +637,8 @@ static const func_info_t func_infos[] = {
F1("password_hash", MAY_BE_STRING), F1("password_hash", MAY_BE_STRING),
#if defined(PHP_CAN_SUPPORT_PROC_OPEN) #if defined(PHP_CAN_SUPPORT_PROC_OPEN)
F1("proc_open", MAY_BE_RESOURCE|MAY_BE_FALSE), 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), 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 #endif
F1("quoted_printable_decode", MAY_BE_STRING), F1("quoted_printable_decode", MAY_BE_STRING),

View file

@ -543,7 +543,7 @@ ZEND_API void zend_ssa_find_false_dependencies(const zend_op_array *op_array, ze
/* }}} */ /* }}} */
/* From "Hacker's Delight" */ /* 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; 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; 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; 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; 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; 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; 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; 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; 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" */ /* 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 . "")*/ \ /* TODO: support for array keys and ($str . "")*/ \
__type |= MAY_BE_RCN; \ __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) { \ if (__ssa_var->alias) { \
__type |= get_ssa_alias_types(__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) \ #define UPDATE_SSA_OBJ_TYPE(_ce, _is_instanceof, var) \
do { \ do { \
if (var >= 0) { \ if (var >= 0) { \
zend_class_entry *__ce = (_ce); \ if (ssa_var_info[var].ce != (_ce) || \
bool __is_instanceof = (_is_instanceof); \ ssa_var_info[var].is_instanceof != (_is_instanceof)) { \
if (__ce && (__ce->ce_flags & ZEND_ACC_FINAL)) { \ ssa_var_info[var].ce = (_ce); \
__is_instanceof = false; \ 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) { \ if (update_worklist) { \
add_usages(op_array, ssa, worklist, var); \ 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 the class is linked, reuse the precise runtime logic. */
if ((ce->ce_flags & ZEND_ACC_LINKED) if ((ce->ce_flags & ZEND_ACC_LINKED)
&& (!scope || (scope->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; EG(fake_scope) = scope;
prop_info = zend_get_property_info(ce, name, 1); prop_info = zend_get_property_info(ce, name, 1);
EG(fake_scope) = prev_scope; EG(fake_scope) = prev_scope;
@ -3023,14 +3024,7 @@ static zend_always_inline zend_result _zend_update_type_info(
break; break;
case ZEND_ASSIGN_OBJ: case ZEND_ASSIGN_OBJ:
if (opline->op1_type == IS_CV) { if (opline->op1_type == IS_CV) {
zend_class_entry *ce = ssa_var_info[ssa_op->op1_use].ce; tmp = (t1 & (MAY_BE_REF|MAY_BE_OBJECT))|MAY_BE_RC1|MAY_BE_RCN;
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);
UPDATE_SSA_TYPE(tmp, ssa_op->op1_def); UPDATE_SSA_TYPE(tmp, ssa_op->op1_def);
COPY_SSA_OBJ_TYPE(ssa_op->op1_use, 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; break;
case ZEND_ASSIGN_OBJ_REF: case ZEND_ASSIGN_OBJ_REF:
if (opline->op1_type == IS_CV && ssa_op->op1_def >= 0) { if (opline->op1_type == IS_CV) {
tmp = t1; tmp = t1;
if (tmp & MAY_BE_OBJECT) { if (tmp & MAY_BE_OBJECT) {
tmp |= MAY_BE_RC1 | MAY_BE_RCN; tmp |= MAY_BE_RC1 | MAY_BE_RCN;
@ -3354,12 +3348,6 @@ static zend_always_inline zend_result _zend_update_type_info(
} }
break; break;
case ZEND_FETCH_CLASS_STATIC: 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: default:
UPDATE_SSA_OBJ_TYPE(NULL, 0, ssa_op->result_def); UPDATE_SSA_OBJ_TYPE(NULL, 0, ssa_op->result_def);
break; 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); 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) { } 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); 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 { } else {
UPDATE_SSA_OBJ_TYPE(NULL, 0, ssa_op->result_def); 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); UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
break; break;
case ZEND_CLONE: 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); UPDATE_SSA_OBJ_TYPE(ce, 1, ssa_op->result_def);
} }
break; 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_FCALL:
case ZEND_DO_ICALL: case ZEND_DO_ICALL:
case ZEND_DO_UCALL: 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); UPDATE_SSA_OBJ_TYPE(zend_ce_closure, /* is_instanceof */ false, ssa_op->result_def);
break; break;
case ZEND_FETCH_CONSTANT: 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); 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; 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_STRLEN:
case ZEND_COUNT: case ZEND_COUNT:
case ZEND_FUNC_NUM_ARGS: case ZEND_FUNC_NUM_ARGS:
@ -4001,73 +3935,12 @@ static zend_always_inline zend_result _zend_update_type_info(
/* Forbidden opcodes */ /* Forbidden opcodes */
ZEND_UNREACHABLE(); ZEND_UNREACHABLE();
break; 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: default:
#ifdef ZEND_DEBUG_TYPE_INFERENCE unknown_opcode:
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
if (ssa_op->op1_def >= 0) { 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; 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); UPDATE_SSA_TYPE(tmp, ssa_op->op1_def);
} }
unknown_opcode:
if (ssa_op->result_def >= 0) { 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; 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) { 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) { switch (opline->opcode) {
case ZEND_NOP: case ZEND_NOP:
case ZEND_IS_IDENTICAL:
case ZEND_IS_NOT_IDENTICAL:
case ZEND_QM_ASSIGN: case ZEND_QM_ASSIGN:
case ZEND_JMP: case ZEND_JMP:
case ZEND_CHECK_VAR: 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_NUM_ARGS:
case ZEND_FUNC_GET_ARGS: case ZEND_FUNC_GET_ARGS:
case ZEND_COPY_TMP: 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: case ZEND_CASE_STRICT:
/* Array to array comparison may lead to recursion. */ case ZEND_JMP_NULL:
return (t1 & t2) & MAY_BE_ARRAY_OF_ARRAY; return 0;
case ZEND_SEND_VAR: case ZEND_SEND_VAR:
case ZEND_SEND_VAL: case ZEND_SEND_VAL:
case ZEND_SEND_REF: 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; return 0;
case ZEND_ASSIGN_DIM: case ZEND_ASSIGN_DIM:
if ((opline+1)->op1_type == IS_CV) { 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; 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; return 1;
} }
if ((opline+1)->op1_type == IS_CV) { 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; return 1;
} }
} }

View file

@ -197,13 +197,13 @@ DEFINE_SSA_OP_DEF_INFO(result)
#define OP1_INFO() (_ssa_op1_info(op_array, ssa, opline, ssa_op)) #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 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 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 ? (ssa_op+1) : NULL)) #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 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 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 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 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 ? (ssa_op+1) : NULL)) #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)) #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) { static zend_always_inline bool zend_add_will_overflow(zend_long a, zend_long b) {

View file

@ -82,8 +82,31 @@ 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) /* {{{ */ zend_result zend_optimizer_eval_cast(zval *result, uint32_t type, zval *op1) /* {{{ */
{ {
if (zend_try_ct_eval_cast(result, type, op1)) { switch (type) {
return SUCCESS; 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; 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_ASSERT_CHECK:
case ZEND_JMP_NULL: case ZEND_JMP_NULL:
case ZEND_BIND_INIT_STATIC_OR_JMP: 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)); ZEND_SET_OP_JMP_ADDR(new_opline, new_opline->op2, ZEND_OP2_JMP_ADDR(opline));
break; break;
case ZEND_FE_FETCH_R: 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_ASSERT_CHECK:
case ZEND_JMP_NULL: case ZEND_JMP_NULL:
case ZEND_BIND_INIT_STATIC_OR_JMP: 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]); ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP2_JMP_ADDR(opline) - shiftlist[ZEND_OP2_JMP_ADDR(opline) - op_array->opcodes]);
break; break;
case ZEND_CATCH: 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( zend_class_entry *zend_optimizer_get_class_entry(
const zend_script *script, const zend_op_array *op_array, zend_string *lcname) { 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; 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; return ce;
} }
zval *ce_zv = zend_hash_find(CG(class_table), lcname); ce = zend_hash_find_ptr(CG(class_table), lcname);
if (ce_zv && !zend_optimizer_ignore_class(ce_zv, op_array ? op_array->filename : NULL)) { if (ce
return Z_PTR_P(ce_zv); && (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)) { 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 } else if (opline->op1_type == IS_UNUSED && op_array->scope
&& !(op_array->scope->ce_flags & ZEND_ACC_TRAIT) && !(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_SELF) {
|| ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_STATIC
&& (op_array->scope->ce_flags & ZEND_ACC_FINAL)))) {
return op_array->scope; return op_array->scope;
} }
return NULL; 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_function *zend_optimizer_get_called_func(
zend_script *script, zend_op_array *op_array, zend_op *opline, bool *is_prototype) 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_string *function_name = Z_STR_P(CRT_CONSTANT(opline->op2));
zend_function *func; zend_function *func;
zval *func_zv;
if (script && (func = zend_hash_find_ptr(&script->function_table, function_name)) != NULL) { if (script && (func = zend_hash_find_ptr(&script->function_table, function_name)) != NULL) {
return func; return func;
} else if ((func_zv = zend_hash_find(EG(function_table), function_name)) != NULL) { } else if ((func = zend_hash_find_ptr(EG(function_table), function_name)) != NULL) {
if (!zend_optimizer_ignore_function(func_zv, op_array->filename)) { if (func->type == ZEND_INTERNAL_FUNCTION) {
return Z_PTR_P(func_zv); return func;
} else if (func->type == ZEND_USER_FUNCTION &&
func->op_array.filename &&
func->op_array.filename == op_array->filename) {
return func;
} }
} }
break; 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) { if (opline->op2_type == IS_CONST && Z_TYPE_P(CRT_CONSTANT(opline->op2)) == IS_STRING) {
zval *function_name = CRT_CONSTANT(opline->op2) + 1; zval *function_name = CRT_CONSTANT(opline->op2) + 1;
zend_function *func; zend_function *func;
zval *func_zv;
if (script && (func = zend_hash_find_ptr(&script->function_table, Z_STR_P(function_name)))) { if (script && (func = zend_hash_find_ptr(&script->function_table, Z_STR_P(function_name)))) {
return func; return func;
} else if ((func_zv = zend_hash_find(EG(function_table), Z_STR_P(function_name))) != NULL) { } else if ((func = zend_hash_find_ptr(EG(function_table), Z_STR_P(function_name))) != NULL) {
if (!zend_optimizer_ignore_function(func_zv, op_array->filename)) { if (func->type == ZEND_INTERNAL_FUNCTION) {
return Z_PTR_P(func_zv); 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; 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: case ZEND_NEW:
{ {
zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1( 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_ASSERT_CHECK:
case ZEND_JMP_NULL: case ZEND_JMP_NULL:
case ZEND_BIND_INIT_STATIC_OR_JMP: case ZEND_BIND_INIT_STATIC_OR_JMP:
case ZEND_JMP_FRAMELESS:
opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes]; opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes];
break; break;
case ZEND_CATCH: 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_ASSERT_CHECK:
case ZEND_JMP_NULL: case ZEND_JMP_NULL:
case ZEND_BIND_INIT_STATIC_OR_JMP: case ZEND_BIND_INIT_STATIC_OR_JMP:
case ZEND_JMP_FRAMELESS:
opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes]; opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes];
break; break;
case ZEND_CATCH: case ZEND_CATCH:
@ -1414,26 +1329,6 @@ static void zend_redo_pass_two_ex(zend_op_array *op_array, zend_ssa *ssa)
} }
break; 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); zend_vm_set_opcode_handler_ex(opline, op1_info, op2_info, res_info);
opline++; 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_foreach_op_array_helper(op_array, func, context);
} }
} ZEND_HASH_FOREACH_END(); } 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(); } ZEND_HASH_FOREACH_END();
} }

View file

@ -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_API void zend_optimizer_unregister_pass(int idx);
zend_result zend_optimizer_startup(void); zend_result zend_optimizer_startup(void);
zend_result zend_optimizer_shutdown(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() END_EXTERN_C()
#endif #endif

View file

@ -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); const zend_script *script, const zend_op_array *op_array, zend_string *lcname);
zend_class_entry *zend_optimizer_get_class_entry_from_op1( 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_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_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx);
void zend_optimizer_pass3(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); 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); 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 #endif

View file

@ -22,7 +22,6 @@
#include "zend_ssa.h" #include "zend_ssa.h"
#include "zend_dump.h" #include "zend_dump.h"
#include "zend_inference.h" #include "zend_inference.h"
#include "zend_worklist.h"
#include "Optimizer/zend_optimizer_internal.h" #include "Optimizer/zend_optimizer_internal.h"
static bool dominates(const zend_basic_block *blocks, int a, int b) { static bool dominates(const zend_basic_block *blocks, int a, int b) {
@ -608,7 +607,7 @@ add_op1_def:
} }
break; break;
case ZEND_ASSIGN_OBJ_REF: 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; ssa_ops[k].op1_def = ssa_vars_count;
var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count; var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
ssa_vars_count++; ssa_vars_count++;
@ -767,35 +766,6 @@ add_op1_def:
//NEW_SSA_VAR(opline->op1.var) //NEW_SSA_VAR(opline->op1.var)
} }
break; 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: default:
break; 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_basic_block *blocks = ssa->cfg.blocks;
zend_ssa_block *ssa_blocks = ssa->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 ssa_vars_count = ssa->vars_count;
int i, j; int i, j;
zend_op *opline, *end; 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) { if (ssa_blocks[n].phis) {
zend_ssa_phi *phi = 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; 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) j = blocks[n].children;
{ while (j >= 0) {
/* The worklist contains block numbers, encoded as positive or negative value. // FIXME: Tail call optimization?
* Positive values indicate that the variable rename still needs to happen for the block. if (zend_ssa_rename(op_array, build_flags, ssa, var, j) == FAILURE)
* Negative values indicate the variable rename was done and all children were handled too. return FAILURE;
* In that case, we will clean up. j = blocks[j].next_child;
* 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];
}
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;
}
} 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); if (tmp) {
ZEND_WORKLIST_STACK_FREE_ALLOCA(&work, work_use_heap); free_alloca(tmp, use_heap);
}
return SUCCESS; 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) /* {{{ */ 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) /* {{{ */
{ {

View file

@ -67,7 +67,7 @@ struct _zend_ssa_phi {
int var; /* Original CV, VAR or TMP variable index */ int var; /* Original CV, VAR or TMP variable index */
int ssa_var; /* SSA variable index */ int ssa_var; /* SSA variable index */
int block; /* current BB index */ int block; /* current BB index */
bool has_range_constraint; bool has_range_constraint : 1;
zend_ssa_phi **use_chains; zend_ssa_phi **use_chains;
zend_ssa_phi *sym_use_chain; zend_ssa_phi *sym_use_chain;
int *sources; /* Array of SSA IDs that produce this var. 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 *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 *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 */ 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) */ unsigned int no_val : 1; /* value doesn't matter (used as op1 in ZEND_ASSIGN) */
bool scc_entry : 1; unsigned int scc_entry : 1;
unsigned int alias : 2; /* value may be changed indirectly */ unsigned int alias : 2; /* value may be changed indirectly */
unsigned int escape_state : 2; unsigned int escape_state : 2;
} zend_ssa_var; } zend_ssa_var;

View file

@ -4,12 +4,13 @@ dnl
dnl ZEND_CHECK_FLOAT_PRECISION dnl ZEND_CHECK_FLOAT_PRECISION
dnl dnl
dnl x87 floating point internal precision control checks 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 dnl
AC_DEFUN([ZEND_CHECK_FLOAT_PRECISION], [dnl AC_DEFUN([ZEND_CHECK_FLOAT_PRECISION],[
AC_CACHE_CHECK([for usable _FPU_SETCW], AC_MSG_CHECKING([for usable _FPU_SETCW])
[php_cv_have__fpu_setcw], AC_LINK_IFELSE([AC_LANG_PROGRAM([[
[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <fpu_control.h>], [dnl #include <fpu_control.h>
]],[[
fpu_control_t fpu_oldcw, fpu_cw; fpu_control_t fpu_oldcw, fpu_cw;
volatile double result; volatile double result;
double a = 2877.0; double a = 2877.0;
@ -20,17 +21,18 @@ AC_CACHE_CHECK([for usable _FPU_SETCW],
_FPU_SETCW(fpu_cw); _FPU_SETCW(fpu_cw);
result = a / b; result = a / b;
_FPU_SETCW(fpu_oldcw); _FPU_SETCW(fpu_oldcw);
(void)result; ]])],[ac_cfp_have__fpu_setcw=yes],[ac_cfp_have__fpu_setcw=no])
])], if test "$ac_cfp_have__fpu_setcw" = "yes" ; then
[php_cv_have__fpu_setcw=yes], AC_DEFINE(HAVE__FPU_SETCW, 1, [whether _FPU_SETCW is present and usable])
[php_cv_have__fpu_setcw=no])]) AC_MSG_RESULT(yes)
AS_VAR_IF([php_cv_have__fpu_setcw], [yes], else
[AC_DEFINE([HAVE__FPU_SETCW], [1], AC_MSG_RESULT(no)
[Define to 1 if _FPU_SETCW is present and usable.])]) fi
AC_CACHE_CHECK([for usable fpsetprec], AC_MSG_CHECKING([for usable fpsetprec])
[php_cv_have_fpsetprec], AC_LINK_IFELSE([AC_LANG_PROGRAM([[
[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <machine/ieeefp.h>], [dnl #include <machine/ieeefp.h>
]],[[
fp_prec_t fpu_oldprec; fp_prec_t fpu_oldprec;
volatile double result; volatile double result;
double a = 2877.0; double a = 2877.0;
@ -40,17 +42,18 @@ AC_CACHE_CHECK([for usable fpsetprec],
fpsetprec(FP_PD); fpsetprec(FP_PD);
result = a / b; result = a / b;
fpsetprec(fpu_oldprec); fpsetprec(fpu_oldprec);
(void)result; ]])], [ac_cfp_have_fpsetprec=yes], [ac_cfp_have_fpsetprec=no])
])], if test "$ac_cfp_have_fpsetprec" = "yes" ; then
[php_cv_have_fpsetprec=yes], AC_DEFINE(HAVE_FPSETPREC, 1, [whether fpsetprec is present and usable])
[php_cv_have_fpsetprec=no])]) AC_MSG_RESULT(yes)
AS_VAR_IF([php_cv_have_fpsetprec], [yes], else
[AC_DEFINE([HAVE_FPSETPREC], [1], AC_MSG_RESULT(no)
[Define to 1 if fpsetprec is present and usable.])]) fi
AC_CACHE_CHECK([for usable _controlfp], AC_MSG_CHECKING([for usable _controlfp])
[php_cv_have__controlfp], AC_LINK_IFELSE([AC_LANG_PROGRAM([[
[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <float.h>], [dnl #include <float.h>
]],[[
unsigned int fpu_oldcw; unsigned int fpu_oldcw;
volatile double result; volatile double result;
double a = 2877.0; double a = 2877.0;
@ -60,17 +63,18 @@ AC_CACHE_CHECK([for usable _controlfp],
_controlfp(_PC_53, _MCW_PC); _controlfp(_PC_53, _MCW_PC);
result = a / b; result = a / b;
_controlfp(fpu_oldcw, _MCW_PC); _controlfp(fpu_oldcw, _MCW_PC);
(void)result; ]])], [ac_cfp_have__controlfp=yes], [ac_cfp_have__controlfp=no])
])], if test "$ac_cfp_have__controlfp" = "yes" ; then
[php_cv_have__controlfp=yes], AC_DEFINE(HAVE__CONTROLFP, 1, [whether _controlfp is present usable])
[php_cv_have__controlfp=no])]) AC_MSG_RESULT(yes)
AS_VAR_IF([php_cv_have__controlfp], [yes], else
[AC_DEFINE([HAVE__CONTROLFP], [1], AC_MSG_RESULT(no)
[Define to 1 if _controlfp is present and usable.])]) fi
AC_CACHE_CHECK([for usable _controlfp_s], AC_MSG_CHECKING([for usable _controlfp_s])
[php_cv_have__controlfp_s], AC_LINK_IFELSE([AC_LANG_PROGRAM([[
[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <float.h>], [dnl #include <float.h>
]],[[
unsigned int fpu_oldcw, fpu_cw; unsigned int fpu_oldcw, fpu_cw;
volatile double result; volatile double result;
double a = 2877.0; double a = 2877.0;
@ -81,17 +85,18 @@ AC_CACHE_CHECK([for usable _controlfp_s],
_controlfp_s(&fpu_cw, _PC_53, _MCW_PC); _controlfp_s(&fpu_cw, _PC_53, _MCW_PC);
result = a / b; result = a / b;
_controlfp_s(&fpu_cw, fpu_oldcw, _MCW_PC); _controlfp_s(&fpu_cw, fpu_oldcw, _MCW_PC);
(void)result; ]])], [ac_cfp_have__controlfp_s=yes], [ac_cfp_have__controlfp_s=no])
])], if test "$ac_cfp_have__controlfp_s" = "yes" ; then
[php_cv_have__controlfp_s=yes], AC_DEFINE(HAVE__CONTROLFP_S, 1, [whether _controlfp_s is present and usable])
[php_cv_have__controlfp_s=no])]) AC_MSG_RESULT(yes)
AS_VAR_IF([php_cv_have__controlfp_s], [yes], else
[AC_DEFINE([HAVE__CONTROLFP_S], [1], AC_MSG_RESULT(no)
[Define to 1 if _controlfp_s is present and usable.])]) fi
AC_CACHE_CHECK([whether FPU control word can be manipulated by inline assembler], AC_MSG_CHECKING([whether FPU control word can be manipulated by inline assembler])
[php_cv_have_fpu_inline_asm_x86], AC_LINK_IFELSE([AC_LANG_PROGRAM([[
[AC_LINK_IFELSE([AC_LANG_PROGRAM([], [dnl /* nothing */
]],[[
unsigned int oldcw, cw; unsigned int oldcw, cw;
volatile double result; volatile double result;
double a = 2877.0; 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)); __asm__ __volatile__ ("fnstcw %0" : "=m" (*&oldcw));
cw = (oldcw & ~0x0 & ~0x300) | 0x200; cw = (oldcw & ~0x0 & ~0x300) | 0x200;
__asm__ __volatile__ ("fldcw %0" : : "m" (*&cw)); __asm__ __volatile__ ("fldcw %0" : : "m" (*&cw));
result = a / b; result = a / b;
__asm__ __volatile__ ("fldcw %0" : : "m" (*&oldcw)); __asm__ __volatile__ ("fldcw %0" : : "m" (*&oldcw));
(void)result; ]])], [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
[php_cv_have_fpu_inline_asm_x86=yes], AC_DEFINE(HAVE_FPU_INLINE_ASM_X86, 1, [whether FPU control word can be manipulated by inline assembler])
[php_cv_have_fpu_inline_asm_x86=no])]) AC_MSG_RESULT(yes)
AS_VAR_IF([php_cv_have_fpu_inline_asm_x86], [yes], else
[AC_DEFINE([HAVE_FPU_INLINE_ASM_X86], [1], AC_MSG_RESULT(no)
[Define to 1 if FPU control word can be manipulated by inline assembler.])]) fi
]) ])
dnl 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
dnl Ugly hack to check if dlsym() requires a leading underscore in symbol name. dnl Ugly hack to check if dlsym() requires a leading underscore in symbol name.
dnl dnl
AC_DEFUN([ZEND_DLSYM_CHECK], [dnl AC_DEFUN([LIBZEND_DLSYM_CHECK],[
AC_MSG_CHECKING([whether dlsym() requires a leading underscore in symbol names]) AC_MSG_CHECKING([whether dlsym() requires a leading underscore in symbol names])
_LT_AC_TRY_DLOPEN_SELF([AC_MSG_RESULT([no])], [ _LT_AC_TRY_DLOPEN_SELF([
AC_MSG_RESULT([yes]) AC_MSG_RESULT(no)
AC_DEFINE([DLSYM_NEEDS_UNDERSCORE], [1], ], [
[Define to 1 if 'dlsym()' requires a leading underscore in symbol names.]) AC_MSG_RESULT(yes)
], [AC_MSG_RESULT([no])], []) AC_DEFINE(DLSYM_NEEDS_UNDERSCORE, 1, [Define if dlsym() requires a leading underscore in symbol names. ])
], [
AC_MSG_RESULT(no)
], [])
]) ])
dnl dnl Checks for library functions.
dnl ZEND_INIT AC_CHECK_FUNCS(getpid kill sigsetjmp pthread_getattr_np pthread_attr_get_np pthread_get_stackaddr_np pthread_attr_getstack pthread_stackseg_np gettid)
dnl
dnl Configure checks and initialization specific for the Zend engine library.
dnl
AC_DEFUN([ZEND_INIT], [dnl
AC_REQUIRE([AC_PROG_CC])
AC_CHECK_HEADERS(m4_normalize([ dnl Test whether the stack grows downwards
cpuid.h dnl Assumes contiguous stack
libproc.h AC_MSG_CHECKING(whether the stack grows downwards)
]))
dnl Check for library functions. AC_RUN_IFELSE([AC_LANG_SOURCE([[
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
#include <stdint.h> #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 (*volatile f)(uintptr_t);
int stack_grows_downwards(uintptr_t arg) { int stack_grows_downwards(uintptr_t arg) {
#ifdef builtin_frame_address int local;
uintptr_t addr = (uintptr_t)builtin_frame_address; return (uintptr_t)&local < arg;
#else
int local;
uintptr_t addr = (uintptr_t)&local;
#endif
return addr < arg;
} }
int main(void) { int main(void) {
#ifdef builtin_frame_address int local;
uintptr_t addr = (uintptr_t)builtin_frame_address;
#else
int local;
uintptr_t addr = (uintptr_t)&local;
#endif
f = stack_grows_downwards; f = stack_grows_downwards;
return f(addr) ? 0 : 1; return f((uintptr_t)&local) ? 0 : 1;
}])], }
[php_cv_have_stack_limit=yes], ]])], [
[php_cv_have_stack_limit=no], AC_DEFINE([ZEND_CHECK_STACK_LIMIT], 1, [Define if checking the stack limit is supported])
[php_cv_have_stack_limit=no])]) AC_MSG_RESULT(yes)
AS_VAR_IF([php_cv_have_stack_limit], [yes], ], [
[AC_DEFINE([ZEND_CHECK_STACK_LIMIT], [1], AC_MSG_RESULT(no)
[Define to 1 if checking the stack limit is supported.])]) ], [
AC_MSG_RESULT(no)
])
ZEND_CHECK_FLOAT_PRECISION
]) ])
dnl dnl
dnl ZEND_CHECK_GLOBAL_REGISTER_VARIABLES dnl LIBZEND_OTHER_CHECKS
dnl dnl
dnl Check whether to enable global register variables if supported. AC_DEFUN([LIBZEND_OTHER_CHECKS],[
dnl
AC_DEFUN([ZEND_CHECK_GLOBAL_REGISTER_VARIABLES], [dnl 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], AC_ARG_ENABLE([gcc-global-regs],
[AS_HELP_STRING([--disable-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=$enableval],
[ZEND_GCC_GLOBAL_REGS=yes]) [ZEND_GCC_GLOBAL_REGS=yes])
AS_VAR_IF([ZEND_GCC_GLOBAL_REGS], [no],, AC_MSG_CHECKING(for global register variables support)
[AC_CACHE_CHECK([whether system supports global register variables], if test "$ZEND_GCC_GLOBAL_REGS" != "no"; then
[php_cv_have_global_register_vars], AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
#if defined(__GNUC__) #if defined(__GNUC__)
# define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) # define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
#else #else
@ -309,158 +364,38 @@ typedef int (*opcode_handler_t)(void);
register void *FP __asm__(ZEND_VM_FP_GLOBAL_REG); register void *FP __asm__(ZEND_VM_FP_GLOBAL_REG);
register const opcode_handler_t *IP __asm__(ZEND_VM_IP_GLOBAL_REG); register const opcode_handler_t *IP __asm__(ZEND_VM_IP_GLOBAL_REG);
int emu(const opcode_handler_t *ip, void *fp) { int emu(const opcode_handler_t *ip, void *fp) {
const opcode_handler_t *orig_ip = IP; const opcode_handler_t *orig_ip = IP;
void *orig_fp = FP; void *orig_fp = FP;
IP = ip; IP = ip;
FP = fp; FP = fp;
while ((*ip)()); while ((*ip)());
FP = orig_fp; FP = orig_fp;
IP = orig_ip; 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])
])
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
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], ZEND_GCC_GLOBAL_REGS=yes
[php_cv_align_mm="(size_t)8 (size_t)3 0"])]) ], [
AS_VAR_IF([php_cv_align_mm], [failed], ZEND_GCC_GLOBAL_REGS=no
[AC_MSG_FAILURE([ZEND_MM alignment defines failed.])], ])
[zend_mm_alignment=$(echo $php_cv_align_mm | cut -d ' ' -f 1) fi
zend_mm_alignment_log2=$(echo $php_cv_align_mm | cut -d ' ' -f 2) if test "$ZEND_GCC_GLOBAL_REGS" = "yes"; then
zend_mm_8byte_realign=$(echo $php_cv_align_mm | cut -d ' ' -f 3) AC_DEFINE([HAVE_GCC_GLOBAL_REGS], 1, [Define if the target system has support for global register variables])
AC_DEFINE_UNQUOTED([ZEND_MM_ALIGNMENT], fi
[$zend_mm_alignment], AC_MSG_RESULT($ZEND_GCC_GLOBAL_REGS)
[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 Check whether __cpuid_count is available.
dnl ZEND_CHECK_SIGNALS AC_CACHE_CHECK(whether __cpuid_count is available, ac_cv_cpuid_count_available, [
dnl AC_LINK_IFELSE([AC_LANG_PROGRAM([[
dnl Check whether to enable Zend signal handling if supported by the system. #include <cpuid.h>
dnl ]], [[
AC_DEFUN([ZEND_CHECK_SIGNALS], [dnl unsigned eax, ebx, ecx, edx;
AC_ARG_ENABLE([zend-signals], __cpuid_count(0, 0, eax, ebx, ecx, edx);
[AS_HELP_STRING([--disable-zend-signals], ]])], [
[Disable Zend signal handling])], ac_cv_cpuid_count_available=yes
[ZEND_SIGNALS=$enableval], ], [
[ZEND_SIGNALS=yes]) ac_cv_cpuid_count_available=no
])])
AC_CHECK_FUNCS([sigaction],, [ZEND_SIGNALS=no]) if test "$ac_cv_cpuid_count_available" = "yes"; then
AS_VAR_IF([ZEND_SIGNALS], [yes], AC_DEFINE([HAVE_CPUID_COUNT], 1, [whether __cpuid_count is available])
[AC_DEFINE([ZEND_SIGNALS], [1], fi
[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])
])

View file

@ -1,133 +1,133 @@
; Copyright Edward Nevill + Oliver Kowalke 2015 ; Copyright Edward Nevill + Oliver Kowalke 2015
; Distributed under the Boost Software License, Version 1.0. ; Distributed under the Boost Software License, Version 1.0.
; (See accompanying file LICENSE_1_0.txt or copy at ; (See accompanying file LICENSE_1_0.txt or copy at
; http://www.boost.org/LICENSE_1_0.txt) ; http://www.boost.org/LICENSE_1_0.txt)
;******************************************************* ;*******************************************************
;* * ;* *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * ;* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * ;* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | d8 | d9 | d10 | d11 | * ;* | d8 | d9 | d10 | d11 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * ;* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * ;* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | d12 | d13 | d14 | d15 | * ;* | d12 | d13 | d14 | d15 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * ;* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * ;* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | x19 | x20 | x21 | x22 | * ;* | x19 | x20 | x21 | x22 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * ;* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * ;* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | x23 | x24 | x25 | x26 | * ;* | x23 | x24 | x25 | x26 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * ;* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * ;* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | x27 | x28 | FP | LR | * ;* | x27 | x28 | FP | LR | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * ;* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| * ;* | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | fiber data| base | limit | dealloc | * ;* | fiber data| base | limit | dealloc | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 48 | 49 | 50 | 51 | | | * ;* | 48 | 49 | 50 | 51 | | | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 0xc0| 0xc4| 0xc8| 0xcc| | | * ;* | 0xc0| 0xc4| 0xc8| 0xcc| | | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | PC | align | | | * ;* | PC | align | | | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* * ;* *
;******************************************************* ;*******************************************************
AREA |.text|, CODE, READONLY, ALIGN=4, CODEALIGN AREA |.text|, CODE, READONLY, ALIGN=4, CODEALIGN
EXPORT jump_fcontext EXPORT jump_fcontext
jump_fcontext proc jump_fcontext proc
; prepare stack for GP + FPU ; prepare stack for GP + FPU
sub sp, sp, #0xd0 sub sp, sp, #0xd0
; save d8 - d15 ; save d8 - d15
stp d8, d9, [sp, #0x00] stp d8, d9, [sp, #0x00]
stp d10, d11, [sp, #0x10] stp d10, d11, [sp, #0x10]
stp d12, d13, [sp, #0x20] stp d12, d13, [sp, #0x20]
stp d14, d15, [sp, #0x30] stp d14, d15, [sp, #0x30]
; save x19-x30 ; save x19-x30
stp x19, x20, [sp, #0x40] stp x19, x20, [sp, #0x40]
stp x21, x22, [sp, #0x50] stp x21, x22, [sp, #0x50]
stp x23, x24, [sp, #0x60] stp x23, x24, [sp, #0x60]
stp x25, x26, [sp, #0x70] stp x25, x26, [sp, #0x70]
stp x27, x28, [sp, #0x80] stp x27, x28, [sp, #0x80]
stp x29, x30, [sp, #0x90] stp x29, x30, [sp, #0x90]
; save LR as PC ; save LR as PC
str x30, [sp, #0xc0] str x30, [sp, #0xc0]
; save current stack base and limit ; save current stack base and limit
ldp x5, x6, [x18, #0x08] ; TeStackBase and TeStackLimit at ksarm64.h ldp x5, x6, [x18, #0x08] ; TeStackBase and TeStackLimit at ksarm64.h
stp x5, x6, [sp, #0xa0] stp x5, x6, [sp, #0xa0]
; save current fiber data and deallocation stack ; save current fiber data and deallocation stack
ldr x5, [x18, #0x1478] ; TeDeallocationStack at ksarm64.h ldr x5, [x18, #0x1478] ; TeDeallocationStack at ksarm64.h
ldr x6, [x18, #0x20] ; TeFiberData at ksarm64.h ldr x6, [x18, #0x20] ; TeFiberData at ksarm64.h
stp x5, x6, [sp, #0xb0] stp x5, x6, [sp, #0xb0]
; store RSP (pointing to context-data) in X0 ; store RSP (pointing to context-data) in X0
mov x4, sp mov x4, sp
; restore RSP (pointing to context-data) from X1 ; restore RSP (pointing to context-data) from X1
mov sp, x0 mov sp, x0
; restore stack base and limit ; restore stack base and limit
ldp x5, x6, [sp, #0xa0] ldp x5, x6, [sp, #0xa0]
stp x5, x6, [x18, #0x08] ; TeStackBase and TeStackLimit at ksarm64.h stp x5, x6, [x18, #0x08] ; TeStackBase and TeStackLimit at ksarm64.h
; restore fiber data and deallocation stack ; restore fiber data and deallocation stack
ldp x5, x6, [sp, #0xb0] ldp x5, x6, [sp, #0xb0]
str x5, [x18, #0x1478] ; TeDeallocationStack at ksarm64.h str x5, [x18, #0x1478] ; TeDeallocationStack at ksarm64.h
str x6, [x18, #0x20] ; TeFiberData at ksarm64.h str x6, [x18, #0x20] ; TeFiberData at ksarm64.h
; load d8 - d15 ; load d8 - d15
ldp d8, d9, [sp, #0x00] ldp d8, d9, [sp, #0x00]
ldp d10, d11, [sp, #0x10] ldp d10, d11, [sp, #0x10]
ldp d12, d13, [sp, #0x20] ldp d12, d13, [sp, #0x20]
ldp d14, d15, [sp, #0x30] ldp d14, d15, [sp, #0x30]
; load x19-x30 ; load x19-x30
ldp x19, x20, [sp, #0x40] ldp x19, x20, [sp, #0x40]
ldp x21, x22, [sp, #0x50] ldp x21, x22, [sp, #0x50]
ldp x23, x24, [sp, #0x60] ldp x23, x24, [sp, #0x60]
ldp x25, x26, [sp, #0x70] ldp x25, x26, [sp, #0x70]
ldp x27, x28, [sp, #0x80] ldp x27, x28, [sp, #0x80]
ldp x29, x30, [sp, #0x90] ldp x29, x30, [sp, #0x90]
; return transfer_t from jump ; return transfer_t from jump
; pass transfer_t as first arg in context function ; pass transfer_t as first arg in context function
; X0 == FCTX, X1 == DATA ; X0 == FCTX, X1 == DATA
mov x0, x4 mov x0, x4
; load pc ; load pc
ldr x4, [sp, #0xc0] ldr x4, [sp, #0xc0]
; restore stack from GP + FPU ; restore stack from GP + FPU
add sp, sp, #0xd0 add sp, sp, #0xd0
ret x4 ret x4
ENDP ENDP
END END

View file

@ -24,10 +24,6 @@
* * * *
****************************************************************************************/ ****************************************************************************************/
#ifdef __x86_64__
#include "jump_x86_64_sysv_elf_gas.S"
#else
.file "jump_i386_sysv_elf_gas.S" .file "jump_i386_sysv_elf_gas.S"
.text .text
.globl jump_fcontext .globl jump_fcontext
@ -95,5 +91,3 @@ jump_fcontext:
/* Mark that we don't need executable stack. */ /* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits .section .note.GNU-stack,"",%progbits
#endif

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -31,16 +31,13 @@
* * * *
****************************************************************************************/ ****************************************************************************************/
# ifdef __i386__ # if defined __CET__
# include "jump_i386_sysv_elf_gas.S" # include <cet.h>
# define SHSTK_ENABLED (__CET__ & 0x2)
# define BOOST_CONTEXT_SHADOW_STACK (SHSTK_ENABLED && SHADOW_STACK_SYSCALL)
# else # else
# if defined __CET__ # define _CET_ENDBR
# include <cet.h> # endif
# define SHSTK_ENABLED (__CET__ & 0x2)
# define BOOST_CONTEXT_SHADOW_STACK (SHSTK_ENABLED && SHADOW_STACK_SYSCALL)
# else
# define _CET_ENDBR
# endif
.file "jump_x86_64_sysv_elf_gas.S" .file "jump_x86_64_sysv_elf_gas.S"
.text .text
.globl jump_fcontext .globl jump_fcontext
@ -151,4 +148,3 @@ jump_fcontext:
/* Mark that we don't need executable stack. */ /* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits .section .note.GNU-stack,"",%progbits
# endif

View file

@ -1,107 +1,107 @@
; Copyright Edward Nevill + Oliver Kowalke 2015 ; Copyright Edward Nevill + Oliver Kowalke 2015
; Distributed under the Boost Software License, Version 1.0. ; Distributed under the Boost Software License, Version 1.0.
; (See accompanying file LICENSE_1_0.txt or copy at ; (See accompanying file LICENSE_1_0.txt or copy at
; http://www.boost.org/LICENSE_1_0.txt) ; http://www.boost.org/LICENSE_1_0.txt)
;******************************************************* ;*******************************************************
;* * ;* *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * ;* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * ;* | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | d8 | d9 | d10 | d11 | * ;* | d8 | d9 | d10 | d11 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * ;* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * ;* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | d12 | d13 | d14 | d15 | * ;* | d12 | d13 | d14 | d15 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * ;* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * ;* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | x19 | x20 | x21 | x22 | * ;* | x19 | x20 | x21 | x22 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * ;* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * ;* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | x23 | x24 | x25 | x26 | * ;* | x23 | x24 | x25 | x26 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * ;* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * ;* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | x27 | x28 | FP | LR | * ;* | x27 | x28 | FP | LR | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * ;* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| * ;* | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | base | limit | dealloc | fiber data| * ;* | base | limit | dealloc | fiber data| *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 48 | 49 | 50 | 51 | | | * ;* | 48 | 49 | 50 | 51 | | | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | 0xc0| 0xc4| 0xc8| 0xcc| | | * ;* | 0xc0| 0xc4| 0xc8| 0xcc| | | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* | PC | align | | | * ;* | PC | align | | | *
;* ------------------------------------------------- * ;* ------------------------------------------------- *
;* * ;* *
;******************************************************* ;*******************************************************
AREA |.text|, CODE, READONLY, ALIGN=4, CODEALIGN AREA |.text|, CODE, READONLY, ALIGN=4, CODEALIGN
EXPORT make_fcontext EXPORT make_fcontext
IMPORT _exit IMPORT _exit
make_fcontext proc make_fcontext proc
; save stack top address to x3 ; save stack top address to x3
mov x3, x0 mov x3, x0
; shift address in x0 (allocated stack) to lower 16 byte boundary ; shift address in x0 (allocated stack) to lower 16 byte boundary
and x0, x0, ~0xF and x0, x0, ~0xF
; reserve space for context-data on context-stack ; reserve space for context-data on context-stack
sub x0, x0, #0xd0 sub x0, x0, #0xd0
; save top address of context_stack as 'base' ; save top address of context_stack as 'base'
str x3, [x0, #0xa0] str x3, [x0, #0xa0]
; save bottom address of context-stack as 'limit' and 'dealloction stack' ; save bottom address of context-stack as 'limit' and 'dealloction stack'
sub x3, x3, x1 sub x3, x3, x1
stp x3, x3, [x0, #0xa8] stp x3, x3, [x0, #0xa8]
; save 0 as 'fiber data' ; save 0 as 'fiber data'
str xzr, [x0, #0xb8] str xzr, [x0, #0xb8]
; third arg of make_fcontext() == address of context-function ; third arg of make_fcontext() == address of context-function
; store address as x19 for trampoline ; store address as x19 for trampoline
str x2, [x0, #0x40] str x2, [x0, #0x40]
; store trampoline address as pc ; store trampoline address as pc
adr x2, trampoline adr x2, trampoline
str x2, [x0, #0xc0] str x2, [x0, #0xc0]
; save address of finish as return-address for context-function ; save address of finish as return-address for context-function
; will be entered after context-function returns (LR register) ; will be entered after context-function returns (LR register)
adr x1, finish adr x1, finish
str x1, [x0, #0x98] str x1, [x0, #0x98]
ret x30 ; return pointer to context-data (x0) ret x30 ; return pointer to context-data (x0)
trampoline trampoline
stp fp, lr, [sp, #-0x10]! stp fp, lr, [sp, #-0x10]!
mov fp, sp mov fp, sp
blr x19 blr x19
finish finish
; exit code is zero ; exit code is zero
mov x0, #0 mov x0, #0
; exit application ; exit application
bl _exit bl _exit
ENDP ENDP
END END

View file

@ -24,10 +24,6 @@
* * * *
****************************************************************************************/ ****************************************************************************************/
#ifdef __x86_64__
#include "make_x86_64_sysv_elf_gas.S"
#else
.file "make_i386_sysv_elf_gas.S" .file "make_i386_sysv_elf_gas.S"
.text .text
.globl make_fcontext .globl make_fcontext
@ -115,5 +111,3 @@ finish:
/* Mark that we don't need executable stack. */ /* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits .section .note.GNU-stack,"",%progbits
#endif

View file

@ -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

View file

@ -64,7 +64,6 @@
* | FCTX | DATA | | | * * | FCTX | DATA | | | *
* ------------------------------------------------- * * ------------------------------------------------- *
* * * *
*******************************************************/
.text .text
.globl _make_fcontext .globl _make_fcontext

View file

@ -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

View file

@ -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 */

View file

@ -31,16 +31,13 @@
* * * *
****************************************************************************************/ ****************************************************************************************/
# ifdef __i386__ # if defined __CET__
# include "make_i386_sysv_elf_gas.S" # include <cet.h>
# define SHSTK_ENABLED (__CET__ & 0x2)
# define BOOST_CONTEXT_SHADOW_STACK (SHSTK_ENABLED && SHADOW_STACK_SYSCALL)
# else # else
# if defined __CET__ # define _CET_ENDBR
# include <cet.h> # endif
# define SHSTK_ENABLED (__CET__ & 0x2)
# define BOOST_CONTEXT_SHADOW_STACK (SHSTK_ENABLED && SHADOW_STACK_SYSCALL)
# else
# define _CET_ENDBR
# endif
.file "make_x86_64_sysv_elf_gas.S" .file "make_x86_64_sysv_elf_gas.S"
.text .text
.globl make_fcontext .globl make_fcontext
@ -187,4 +184,3 @@ finish:
/* Mark that we don't need executable stack. */ /* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits .section .note.GNU-stack,"",%progbits
# endif

View file

@ -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
View 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
View 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