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 1077503 deletions

View file

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

View file

@ -32,7 +32,3 @@ max_line_length = 80
[*.patch]
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.
**/*_arginfo.h linguist-generated -diff
/main/debug_gdb_scripts.c linguist-generated -diff
/Zend/zend_vm_execute.h linguist-generated -diff
/Zend/zend_vm_handlers.h linguist-generated -diff
/Zend/zend_vm_opcodes.[ch] linguist-generated -diff
# The OSS fuzz files are binary
# The OSS fuzz files are bunary
/ext/date/tests/ossfuzz*.txt binary
# Vendored libraries
/ext/lexbor/lexbor linguist-vendored
/ext/uri/uriparser linguist-vendored

5
.github/CODEOWNERS vendored
View file

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

View file

@ -22,23 +22,15 @@ body:
```
validations:
required: true
- type: textarea
- type: input
attributes:
label: PHP Version
description: |
Please run PHP with the `-v` flag (e.g. `php -v`, `php8.3 -v`, `php-fpm -v` or similar) and provide the full output of that command. If executing that command is not possible, please provide the full version number as given in PHPInfo.
Please make sure that the used PHP version [is a supported version](https://www.php.net/supported-versions.php).
placeholder: |
PHP 8.3.19 (cli) (built: Mar 13 2025 17:44:40) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.19, Copyright (c) Zend Technologies
with Zend OPcache v8.3.19, Copyright (c), by Zend Technologies
render: plain
description: "The used PHP version. Make sure it is [supported](https://www.php.net/supported-versions.php)."
placeholder: "PHP 8.0.12"
validations:
required: true
- type: input
attributes:
label: Operating System
description: "The used operating system, if relevant."
placeholder: "Ubuntu 24.04"
placeholder: "Ubuntu 20.04"

View file

@ -3,3 +3,6 @@ contact_links:
- name: Documentation issue
url: https://github.com/php/doc-en/issues
about: Please report documentation issues on the doc-en repository.
- name: Security issue
url: https://bugs.php.net/report.php?security_bug
about: Please report security issues in this private bug tracker.

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

View file

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

View file

@ -11,9 +11,6 @@ runs:
code=" keg.link\(verbose: verbose\?"
sudo sed -Ei '' "s/$code.*/$code, overwrite: true\)/" "$formula_installer"
# Some packages exist on x86 but not arm, or vice versa.
# Install them with reinstall to avoid warnings.
brew reinstall autoconf webp tidy-html5 libzip libsodium icu4c curl
brew install \
bison \
re2c
@ -22,6 +19,7 @@ runs:
enchant \
libffi \
intltool \
icu4c \
libiconv \
t1lib \
libxml2 \

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

View file

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

View file

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

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

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/bigtest /etc/snmp
sudo service snmpd restart
sudo groupadd -g 5000 vmail
sudo useradd -m -d /var/vmail -s /bin/false -u 5000 -g vmail vmail
sudo cp ext/imap/tests/setup/dovecot.conf /etc/dovecot/dovecot.conf
sudo cp ext/imap/tests/setup/dovecotpass /etc/dovecot/dovecotpass
sudo service dovecot restart

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_USER="pdo_test"
export PDO_DBLIB_TEST_PASS="password"
export PHP_OCI8_TEST_USER="system"
export PHP_OCI8_TEST_PASS="pass"
export PHP_OCI8_TEST_DB="localhost/XEPDB1"
export PDO_OCI_TEST_USER="system"
export PDO_OCI_TEST_PASS="pass"
export PDO_OCI_TEST_DSN="oci:dbname=localhost/XEPDB1;charset=AL32UTF8"
export PGSQL_TEST_CONNSTR="host=localhost dbname=test port=5432 user=postgres password=postgres"
if [[ -z "$PDO_PGSQL_TEST_DSN" ]]; then
export PDO_PGSQL_TEST_DSN="pgsql:host=localhost port=5432 dbname=test user=postgres password=postgres"
fi
export PDO_FIREBIRD_TEST_DATABASE=test.fdb
if [[ -z "$PDO_FIREBIRD_TEST_DSN" ]]; then
export PDO_FIREBIRD_TEST_DSN=firebird:dbname=localhost:test.fdb
fi
export PDO_FIREBIRD_TEST_PASS=test
export PDO_FIREBIRD_TEST_USER=test
export ODBC_TEST_USER="odbc_test"
export ODBC_TEST_PASS="password"
export ODBC_TEST_DSN="Driver={ODBC Driver 17 for SQL Server};Server=127.0.0.1;Database=odbc;uid=$ODBC_TEST_USER;pwd=$ODBC_TEST_PASS"
@ -43,8 +43,7 @@ runs:
export STACK_LIMIT_DEFAULTS_CHECK=1
sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \
-d opcache.jit=${{ inputs.jitType }} \
-d opcache.protect_memory=1 \
-d opcache.jit_buffer_size=64M \
-d opcache.jit_buffer_size=16M \
${{ inputs.idleCpu == 'true' && '-j$(($(/usr/bin/nproc) - 1))' || '-j$(/usr/bin/nproc)' }} \
-g FAIL,BORK,LEAK,XLEAK \
--no-progress \

View file

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

View file

@ -4,13 +4,13 @@ runs:
steps:
- shell: bash
run: |
set -ex
[[ "$OSTYPE" == "darwin"* ]] && export PATH="$(brew --prefix)/opt/bison/bin:$PATH"
set -x
[[ "$OSTYPE" == "darwin"* ]] && export PATH="/usr/local/opt/bison/bin:$PATH"
scripts/dev/credits
scripts/dev/genfiles
scripts/gdb/debug_gdb_scripts_gen.php
Zend/zend_vm_gen.php
ext/tokenizer/tokenizer_data_gen.php
build/gen_stub.php -f --generate-optimizer-info --verify
build/gen_stub.php -f
build/gen_stub.php --generate-optimizer-info
# Use the -a flag for a bug in git 2.46.0, which doesn't consider changed -diff files.
git add . -N && git diff -a --exit-code

517
.github/labeler.yml vendored
View file

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

View file

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

View file

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

View file

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

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_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
)

View file

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

View file

@ -1,3 +1,5 @@
@echo off
if /i "%GITHUB_ACTIONS%" neq "True" (
echo for CI only
exit /b 3
@ -51,22 +53,19 @@ set PDOTEST_DSN=odbc:%ODBC_TEST_DSN%
rem setup Firebird related exts
if "%PLATFORM%" == "x64" (
set PHP_FIREBIRD_DOWNLOAD_URL=https://github.com/FirebirdSQL/firebird/releases/download/v4.0.4/Firebird-4.0.4.3010-0-x64.zip
set PHP_FIREBIRD_DOWNLOAD_URL=https://github.com/FirebirdSQL/firebird/releases/download/v3.0.9/Firebird-3.0.9.33560-0_x64.zip
) else (
set PHP_FIREBIRD_DOWNLOAD_URL=https://github.com/FirebirdSQL/firebird/releases/download/v4.0.4/Firebird-4.0.4.3010-0-Win32.zip
set PHP_FIREBIRD_DOWNLOAD_URL=https://github.com/FirebirdSQL/firebird/releases/download/v3.0.9/Firebird-3.0.9.33560-0_Win32.zip
)
curl -sLo Firebird.zip %PHP_FIREBIRD_DOWNLOAD_URL%
7z x -oC:\Firebird Firebird.zip
set PDO_FIREBIRD_TEST_DATABASE=C:\test.fdb
set PDO_FIREBIRD_TEST_DSN=firebird:dbname=127.0.0.1:%PDO_FIREBIRD_TEST_DATABASE%
set PDO_FIREBIRD_TEST_DSN=firebird:dbname=%PDO_FIREBIRD_TEST_DATABASE%
set PDO_FIREBIRD_TEST_USER=SYSDBA
set PDO_FIREBIRD_TEST_PASS=phpfi
echo create user %PDO_FIREBIRD_TEST_USER% password '%PDO_FIREBIRD_TEST_PASS%';> C:\Firebird\create_user.sql
echo commit;>> C:\Firebird\create_user.sql
echo create database '%PDO_FIREBIRD_TEST_DATABASE%' user '%PDO_FIREBIRD_TEST_USER%' password '%PDO_FIREBIRD_TEST_PASS%';> C:\Firebird\setup.sql
C:\Firebird\instsvc.exe install -n TestInstance
C:\Firebird\isql -q -i C:\Firebird\setup.sql
C:\Firebird\isql -q -i C:\Firebird\create_user.sql -user sysdba %PDO_FIREBIRD_TEST_DATABASE%
C:\Firebird\instsvc.exe start -n TestInstance
if %errorlevel% neq 0 exit /b 3
path C:\Firebird;%PATH%
@ -91,7 +90,9 @@ set OPENSSL_CONF=
rem set SSLEAY_CONF=
rem prepare for OPcache
if "%OPCACHE%" equ "1" set OPCACHE_OPTS=-d opcache.enable=1 -d opcache.enable_cli=1 -d opcache.protect_memory=1 -d opcache.jit_buffer_size=64M -d opcache.jit=tracing
if "%OPCACHE%" equ "1" set OPCACHE_OPTS=-d opcache.enable=1 -d opcache.enable_cli=1 -d opcache.protect_memory=1 -d opcache.jit_buffer_size=16M
rem work-around for failing to dl(mysqli) with OPcache (https://github.com/php/php-src/issues/8508)
if "%OPCACHE%" equ "1" set OPCACHE_OPTS=%OPCACHE_OPTS% -d extension=mysqli
rem prepare for enchant
mkdir %~d0\usr\local\lib\enchant-2
@ -109,7 +110,6 @@ popd
rem prepare for snmp
set MIBDIRS=%DEPS_DIR%\share\mibs
sed -i "s/exec HexTest .*/exec HexTest cscript\.exe \/nologo %GITHUB_WORKSPACE:\=\/%\/ext\/snmp\/tests\/bigtest\.js/g" %GITHUB_WORKSPACE%\ext\snmp\tests\snmpd.conf
start %DEPS_DIR%\bin\snmpd.exe -C -c %GITHUB_WORKSPACE%\ext\snmp\tests\snmpd.conf -Ln
set PHP_BUILD_DIR=%PHP_BUILD_OBJ_DIR%\Release
@ -119,42 +119,37 @@ rem prepare for mail
curl -sLo hMailServer.exe https://www.hmailserver.com/download_file/?downloadid=271
hMailServer.exe /verysilent
cd %APPVEYOR_BUILD_FOLDER%
%PHP_BUILD_DIR%\php.exe -dextension_dir=%PHP_BUILD_DIR% -dextension=com_dotnet .github\setup_hmailserver.php
rem prepare for com_dotnet
nmake register_comtest
%PHP_BUILD_DIR%\php.exe -dextension_dir=%PHP_BUILD_DIR% -dextension=com_dotnet appveyor\setup_hmailserver.php
mkdir %PHP_BUILD_DIR%\test_file_cache
rem generate php.ini
echo extension_dir=%PHP_BUILD_DIR% > %PHP_BUILD_DIR%\php.ini
echo opcache.file_cache=%PHP_BUILD_DIR%\test_file_cache >> %PHP_BUILD_DIR%\php.ini
echo opcache.record_warnings=1 >> %PHP_BUILD_DIR%\php.ini
if "%OPCACHE%" equ "1" echo zend_extension=php_opcache.dll >> %PHP_BUILD_DIR%\php.ini
rem work-around for some spawned PHP processes requiring OpenSSL and sockets
echo extension=php_openssl.dll >> %PHP_BUILD_DIR%\php.ini
echo extension=php_sockets.dll >> %PHP_BUILD_DIR%\php.ini
rem remove ext dlls for which tests are not supported
for %%i in (ldap) do (
for %%i in (ldap oci8_12c pdo_oci) do (
del %PHP_BUILD_DIR%\php_%%i.dll
)
rem reduce excessive stack reserve for testing
editbin /stack:8388608 %PHP_BUILD_DIR%\php.exe
editbin /stack:8388608 %PHP_BUILD_DIR%\php-cgi.exe
set TEST_PHPDBG_EXECUTABLE=%PHP_BUILD_DIR%\phpdbg.exe
copy /-y %DEPS_DIR%\bin\*.dll %PHP_BUILD_DIR%\*
if "%ASAN%" equ "1" set ASAN_OPTS=--asan
mkdir c:\tests_tmp
nmake test TESTS="%OPCACHE_OPTS% -g FAIL,BORK,LEAK,XLEAK %ASAN_OPTS% --no-progress -q --offline --show-diff --show-slow 1000 --set-timeout 120 --temp-source c:\tests_tmp --temp-target c:\tests_tmp %PARALLEL%"
nmake test TESTS="%OPCACHE_OPTS% -g FAIL,BORK,LEAK,XLEAK --no-progress -q --offline --show-diff --show-slow 1000 --set-timeout 120 --temp-source c:\tests_tmp --temp-target c:\tests_tmp --bless %PARALLEL%"
set EXIT_CODE=%errorlevel%
nmake unregister_comtest
taskkill /f /im snmpd.exe
if %EXIT_CODE% GEQ 1 (
git checkout ext\pgsql\tests\config.inc
git diff > bless_tests.patch
)
exit /b %EXIT_CODE%

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:
build:
if: github.repository == 'php/php-src'
if: github.repository_owner == 'php'
runs-on: ubuntu-latest
permissions:
issues: write

View file

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

View file

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

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
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v5
- uses: actions/labeler@v4
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"

View file

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

View file

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

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:
build:
if: "github.repository == 'php/php-src' && contains(github.event.issue.labels.*.name, 'Status: Needs Feedback') && github.event.issue.user.login == github.event.sender.login"
if: "github.repository_owner == 'php' && contains(github.event.issue.labels.*.name, 'Status: Needs Feedback') && github.event.issue.user.login == github.event.sender.login"
runs-on: ubuntu-latest
permissions:
issues: write

View file

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

21
.gitignore vendored
View file

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

92
.travis.yml Normal file
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. PHP is implemented in C11.
For instance, the optional fixed-width integers from
1. PHP is implemented in C99. The optional fixed-width integers from
stdint.h (int8_t, int16_t, int32_t, int64_t and their unsigned
counterparts) are supposed to be available.
counterparts) must be available.
1. Functions that are given pointers to resources should not free them.
@ -56,6 +55,11 @@ rewritten to comply with these rules.
the source. Although the `PHP_*` macros are mostly aliased to the `ZEND_*`
macros it gives a better understanding on what kind of macro you're calling.
1. When commenting out code using a `#if` statement, do NOT use `0` only.
Instead, use `"<git username here>_0"`. For example, `#if FOO_0`,
where `FOO` is your git user `foo`. This allows easier tracking of why
code was commented out, especially in bundled libraries.
1. Do not define functions that are not available. For instance, if a library is
missing a function, do not define the PHP version of the function, and do
not raise a run-time error about the function not existing. End users should
@ -148,74 +152,62 @@ rewritten to comply with these rules.
1. Method names follow the *studlyCaps* (also referred to as *bumpy case* or
*camel caps*) naming convention, with care taken to minimize the letter
count. The initial letter of the name is lowercase, and each letter that
starts a new "word" is capitalized.
starts a new `word` is capitalized:
1. Class names should be descriptive nouns in *PascalCase* and as short as
possible. Each word in the class name should start with a capital letter,
without underscore delimiters. The class name should be prefixed with the
name of the "parent set" (e.g. the name of the extension) if no namespaces
are used.
1. Abbreviations and acronyms as well as initialisms should be avoided wherever
possible, unless they are much more widely used than the long form (e.g. HTTP
or URL). Abbreviations, acronyms, and initialisms should be treated like
regular words, thus they should be written with an uppercase first character,
followed by lowercase characters.
1. Diverging from this policy is allowed to keep internal consistency within a
single extension, if the name follows an established, language-agnostic
standard, or for other reasons, if those reasons are properly justified
and voted on as part of the RFC process.
Good method names:
Good:
```php
connect()
getData()
buildSomeWidget()
performHttpRequest()
```
Bad method names:
Bad:
```php
get_Data()
buildsomewidget()
getI()
performHTTPRequest()
```
Good class names:
1. Class names should be descriptive nouns in *PascalCase* and as short as
possible. Each word in the class name should start with a capital letter,
without underscore delimiters. The class name should be prefixed with the
name of the "parent set" (e.g. the name of the extension) if no namespaces
are used. Abbreviations and acronyms as well as initialisms should be
avoided wherever possible, unless they are much more widely used than the
long form (e.g. HTTP or URL). Abbreviations start with a capital letter
followed by lowercase letters, whereas acronyms and initialisms are written
according to their standard notation. Usage of acronyms and initialisms is
not allowed if they are not widely adopted and recognized as such.
Good:
```php
Curl
CurlResponse
HttpStatusCode
Url
BtreeMap // B-tree Map
UserId // User Identifier
HTTPStatusCode
URL
BTreeMap // B-tree Map
Id // Identifier
ID // Identity Document
Char // Character
Intl // Internationalization
Ssl\Certificate
Ssl\Crl // Certificate Revocation List
Ssl\CrlUrl
Radar // Radio Detecting and Ranging
```
Bad class names:
Bad:
```php
curl
curl_response
HTTPStatusCode
URL
BTreeMap
UserID // User Identifier
HttpStatusCode
Url
BtreeMap
ID // Identifier
CHAR
INTL
SSL\Certificate
SSL\CRL
SSL\CRLURL
RADAR // Radio Detecting and Ranging
```
## Internal function naming conventions

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
implement RFCs. Please be sure to include tests as appropriate!
By submitting a pull request, you certify that you have the necessary rights
to submit the work, that the work does not violate any third-party rights
(including those of your employer, if applicable), and that you license your
contribution under the PHP License or under another license if explicitly
accepted by the PHP project maintainers.
If you are fixing a bug, then please submit your PR against the lowest actively
supported branch of PHP that the bug affects (only green branches on
[the supported version page](https://www.php.net/supported-versions.php) are
@ -137,8 +131,12 @@ should be credited, the `Co-authored-by` tag in the commit message may be used.
## Writing documentation
Editing the manual is done by checking out the XML sources using Git and editing
and building it [per the instructions on the documentation site](http://doc.php.net/tutorial/).
There are two ways to contribute to the PHP manual. You can edit the manual and
send patches anonymously via [the online editor](https://edit.php.net/), or you
can check the XML source out from Subversion and edit that and build it
[per the instructions on the documentation site](http://doc.php.net/tutorial/).
Patches created that way should be sent to the
[documentation mailing list](mailto:phpdoc@lists.php.net).
## Getting help
@ -208,9 +206,6 @@ locations.
├─ libmbfl/ # Forked and maintained in php-src
├─ unicode_data.h # Generated by `ext/mbstring/ucgendat/ucgendat.php`
└─ ...
└─ opcache/
└─ jit/
└─ ir/ # Bundled part of IR framework https://github.com/dstogov/ir
└─ pcre/
├─ pcre2lib/ # https://www.pcre.org/
└─ ...
@ -244,6 +239,7 @@ locations.
└─ ...
├─ scripts/ # php-config, phpize and internal development scripts
├─ tests/ # Core features tests
├─ travis/ # Travis CI service files
└─ win32/ # Windows build system files
├─ cp_enc_map.c # Generated by `win32/cp_enc_map_gen.exe`
└─ ...
@ -356,12 +352,10 @@ Currently, we have the following branches in use:
| Branch | |
| --------- | --------- |
| master | Active development branch for PHP 8.5, which is open for backwards incompatible changes and major internal API changes. |
| PHP-8.4 | Is used to release the PHP 8.4.x series. This is a current stable version and is open for bugfixes only. |
| PHP-8.3 | Is used to release the PHP 8.3.x series. This is a current stable version and is open for bugfixes only. |
| PHP-8.2 | Is used to release the PHP 8.2.x series. This is an old stable version and is open for security fixes only. |
| PHP-8.1 | Is used to release the PHP 8.1.x series. This is an old stable version and is open for security fixes only. |
| PHP-8.0 | This branch is closed. |
| master | Active development branch for PHP 8.3, which is open for backwards incompatible changes and major internal API changes. |
| PHP-8.2 | Is used to release the PHP 8.2.x series. This is a current stable version and is open for bugfixes only. |
| PHP-8.1 | Is used to release the PHP 8.1.x series. This is a current stable version and is open for bugfixes only. |
| PHP-8.0 | Is used to release the PHP 8.0.x series. This is an old stable version and is open for security fixes only. |
| PHP-7.4 | This branch is closed. |
| PHP-7.3 | This branch is closed. |
| PHP-7.2 | This branch is closed. |

View file

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

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
18. avifinfo (ext/standard/libavifinfo) see ext/standard/libavifinfo/LICENSE
19. xxHash (ext/hash/xxhash)
20. Lexbor (ext/lexbor/lexbor) see ext/lexbor/LICENSE
21. Portions of libcperciva (ext/hash/hash_sha_{ni,sse2}.c) see the header in the source file
22. uriparser (ext/uri/uriparser) see ext/uri/uriparser/COPYING
3. pcre2lib (ext/pcre)

View file

@ -1,5 +1,5 @@
<div align="center">
<a href="https://www.php.net">
<a href="https://php.net">
<img
alt="PHP"
src="https://www.php.net/images/logos/new-php-logo.svg"
@ -15,11 +15,12 @@ blog to the most popular websites in the world. PHP is distributed under the
[PHP License v3.01](LICENSE).
[![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
The PHP manual is available at [php.net/docs](https://www.php.net/docs).
The PHP manual is available at [php.net/docs](https://php.net/docs).
## Installation
@ -31,7 +32,7 @@ For Windows, the PHP binaries can be obtained from
[windows.php.net](https://windows.php.net). After extracting the archive the
`*.exe` files are ready to use.
For other systems, see the [installation chapter](https://www.php.net/install).
For other systems, see the [installation chapter](https://php.net/install).
### Building PHP source code
@ -42,50 +43,28 @@ a default build, you will additionally need libxml2 and libsqlite3.
On Ubuntu, you can install these using:
```shell
sudo apt install -y pkg-config build-essential autoconf bison re2c libxml2-dev libsqlite3-dev
```
sudo apt install -y pkg-config build-essential autoconf bison re2c \
libxml2-dev libsqlite3-dev
On Fedora, you can install these using:
```shell
sudo dnf install re2c bison autoconf make libtool ccache libxml2-devel sqlite-devel
```
On MacOS, you can install these using `brew`:
```shell
brew install autoconf bison re2c iconv libxml2 sqlite
```
or with `MacPorts`:
```shell
sudo port install autoconf bison re2c libiconv libxml2 sqlite3
```
sudo dnf install re2c bison autoconf make libtool ccache libxml2-devel sqlite-devel
Generate configure:
```shell
./buildconf
```
./buildconf
Configure your build. `--enable-debug` is recommended for development, see
`./configure --help` for a full list of options.
```shell
# For development
./configure --enable-debug
# For production
./configure
```
# For development
./configure --enable-debug
# For production
./configure
Build PHP. To speed up the build, specify the maximum number of jobs using the
`-j` argument:
Build PHP. To speed up the build, specify the maximum number of jobs using `-j`:
```shell
make -j4
```
make -j4
The number of jobs should usually match the number of available cores, which
can be determined using `nproc`.
@ -96,21 +75,13 @@ PHP ships with an extensive test suite, the command `make test` is used after
successful compilation of the sources to run this test suite.
It is possible to run tests using multiple cores by setting `-jN` in
`TEST_PHP_ARGS` or `TESTS`:
`TEST_PHP_ARGS`:
```shell
make TEST_PHP_ARGS=-j4 test
```
make TEST_PHP_ARGS=-j4 test
Shall run `make test` with a maximum of 4 concurrent jobs: Generally the maximum
number of jobs should not exceed the number of cores available.
Use the `TEST_PHP_ARGS` or `TESTS` variable to test only specific directories:
```shell
make TESTS=tests/lang/ test
```
The [qa.php.net](https://qa.php.net) site provides more detailed info about
testing and quality assurance.
@ -118,11 +89,9 @@ testing and quality assurance.
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.
## PHP extensions
@ -162,11 +131,10 @@ contribute:
- [Contributing to PHP](/CONTRIBUTING.md)
- [PHP coding standards](/CODING_STANDARDS.md)
- [Internal documentation](https://php.github.io/php-src/)
- [Mailing list rules](/docs/mailinglist-rules.md)
- [PHP release process](/docs/release-process.md)
## Credits
For the list of people who've put work into PHP, please see the
[PHP credits page](https://www.php.net/credits.php).
[PHP credits page](https://php.net/credits.php).

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_API void ts_apply_for_id(ts_rsrc_id id, void (*cb)(void *))
{
int rsrc_id = TSRM_UNSHUFFLE_RSRC_ID(id);
tsrm_mutex_lock(tsmm_mutex);
if (tsrm_tls_table && resource_types_table) {
for (int i = 0; i < tsrm_tls_table_size; i++) {
tsrm_tls_entry *p = tsrm_tls_table[i];
while (p) {
if (p->count > rsrc_id && p->storage[rsrc_id]) {
cb(p->storage[rsrc_id]);
}
p = p->next;
}
}
}
tsrm_mutex_unlock(tsmm_mutex);
}
/*
* Utility Functions
@ -777,16 +756,14 @@ TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void)
// TODO: Implement support for fast JIT ZTS code ???
return 0;
#elif defined(__x86_64__) && defined(__GNUC__) && !defined(__FreeBSD__) && \
!defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) && \
!defined(__HAIKU__) && !defined(__CYGWIN__)
!defined(__OpenBSD__) && !defined(__MUSL__) && !defined(__HAIKU__)
size_t ret;
asm ("movq _tsrm_ls_cache@gottpoff(%%rip),%0"
: "=r" (ret));
return ret;
#elif defined(__i386__) && defined(__GNUC__) && !defined(__FreeBSD__) && \
!defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__MUSL__) && \
!defined(__HAIKU__) && !defined(__CYGWIN__)
!defined(__OpenBSD__) && !defined(__MUSL__) && !defined(__HAIKU__)
size_t ret;
asm ("leal _tsrm_ls_cache@ntpoff,%0"

View file

@ -13,11 +13,11 @@
#ifndef TSRM_H
#define TSRM_H
#if !defined(__CYGWIN__) && defined(_WIN32)
#if !defined(__CYGWIN__) && defined(WIN32)
# define TSRM_WIN32
# include <Zend/zend_config.w32.h>
# include "Zend/zend_config.w32.h"
#else
# include <main/php_config.h>
# include "main/php_config.h"
#endif
#include <stdint.h>
@ -104,9 +104,6 @@ TSRM_API void ts_free_thread(void);
/* deallocates all occurrences of a given id */
TSRM_API void ts_free_id(ts_rsrc_id id);
/* Runs a callback on all resources of the given id.
* The caller is responsible for ensuring the underlying resources don't data-race. */
TSRM_API void ts_apply_for_id(ts_rsrc_id id, void (*cb)(void *));
/* Debug support */
#define TSRM_ERROR_LEVEL_ERROR 1
@ -152,7 +149,7 @@ TSRM_API bool tsrm_is_managed_thread(void);
# define __has_attribute(x) 0
#endif
#if !__has_attribute(tls_model) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__MUSL__) || defined(__HAIKU__)
#if !__has_attribute(tls_model) || defined(__FreeBSD__) || defined(__MUSL__) || defined(__HAIKU__)
# define TSRM_TLS_MODEL_ATTR
# define TSRM_TLS_MODEL_DEFAULT
#elif __PIC__

View file

@ -31,6 +31,12 @@ dnl
dnl Set some magic defines to achieve POSIX threads conformance.
dnl
AC_DEFUN([PTHREADS_FLAGS],[
if test -z "$host_alias" && test -n "$host"; then
host_alias=$host
fi
if test -z "$host_alias"; then
AC_MSG_ERROR(host_alias is not set. Make sure to run config.guess)
fi
case $host_alias in
*solaris*)
PTHREAD_FLAGS="-D_POSIX_PTHREAD_SEMANTICS -D_REENTRANT";;
@ -40,6 +46,8 @@ AC_DEFUN([PTHREADS_FLAGS],[
PTHREAD_FLAGS=-D_REENTRANT;;
*aix*)
PTHREAD_FLAGS=-D_THREAD_SAFE;;
*irix*)
PTHREAD_FLAGS=-D_POSIX_THREAD_SAFE_FUNCTIONS;;
*hpux*)
PTHREAD_FLAGS=-D_REENTRANT;;
*sco*)
@ -126,7 +134,7 @@ if test "$pthreads_working" != "yes"; then
fi
])
if test "x$ac_cv_pthreads_cflags" != "x" || test "x$ac_cv_pthreads_lib" != "x"; then
if test "x$ac_cv_pthreads_cflags" != "x" -o "x$ac_cv_pthreads_lib" != "x"; then
pthreads_working="yes"
fi
])

17
TSRM/tsrm.m4 Normal file
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;
}
size_t cmd_buffer_size = strlen(command) + strlen(TWG(comspec)) + sizeof(" /s /c ") + 2;
cmd = malloc(cmd_buffer_size);
cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /s /c ")+2);
if (!cmd) {
return NULL;
}
snprintf(cmd, cmd_buffer_size, "%s /s /c \"%s\"", TWG(comspec), command);
sprintf(cmd, "%s /s /c \"%s\"", TWG(comspec), command);
cmdw = php_win32_cp_any_to_w(cmd);
if (!cmdw) {
free(cmd);
@ -636,7 +635,7 @@ TSRM_API int shmget(key_t key, size_t size, int flags)
{/*{{{*/
shm_pair *shm;
char shm_segment[sizeof(SEGMENT_PREFIX INT_MIN_AS_STRING)];
HANDLE shm_handle = NULL;
HANDLE shm_handle = NULL, info_handle = NULL;
BOOL created = FALSE;
if (key != IPC_PRIVATE) {

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

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
$(srcdir)/zend_language_scanner.c $(srcdir)/zend_language_scanner_defs.h: $(srcdir)/zend_language_scanner.l
@(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt Zend/zend_language_scanner_defs.h -oZend/zend_language_scanner.c Zend/zend_language_scanner.l)
@(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt Zend/zend_language_scanner_defs.h -oZend/zend_language_scanner.c Zend/zend_language_scanner.l)
$(srcdir)/zend_language_parser.h: $(srcdir)/zend_language_parser.c
$(srcdir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y
@ -23,10 +23,10 @@ $(srcdir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y
$(srcdir)/zend_ini_parser.h: $(srcdir)/zend_ini_parser.c
$(srcdir)/zend_ini_parser.c: $(srcdir)/zend_ini_parser.y
@$(YACC) $(YFLAGS) -v -d $(srcdir)/zend_ini_parser.y -o $@
$(YACC) $(YFLAGS) -v -d $(srcdir)/zend_ini_parser.y -o $@
$(srcdir)/zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l
@(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt Zend/zend_ini_scanner_defs.h -oZend/zend_ini_scanner.c Zend/zend_ini_scanner.l)
@(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt Zend/zend_ini_scanner_defs.h -oZend/zend_ini_scanner.c Zend/zend_ini_scanner.l)
# Use an intermediate target to indicate that zend_vm_gen.php produces both files
# at the same time, rather than the same recipe applying for two different targets.

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,
* hence removing the temporary is not safe in the general case, especially when other consumers are not FREE.
* A FREE may not be removed without also removing the source's result, because otherwise that would cause a memory leak. */
if (opline->extended_value == ZEND_FREE_VOID_CAST) {
/* Keep the ZEND_FREE opcode alive. */
} else if (opline->op1_type == IS_TMP_VAR) {
if (opline->op1_type == IS_TMP_VAR) {
src = VAR_SOURCE(opline->op1);
if (src) {
switch (src->opcode) {
@ -420,14 +418,6 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
}
break;
case ZEND_EXT_STMT:
if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
/* Variable will be deleted later by FREE, so we can't optimize it */
Tsource[VAR_NUM(opline->op1.var)] = NULL;
break;
}
break;
case ZEND_CASE:
case ZEND_CASE_STRICT:
case ZEND_COPY_TMP:
@ -478,67 +468,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
goto optimize_bool;
}
break;
case ZEND_IS_IDENTICAL:
if (opline->op1_type == IS_CONST &&
opline->op2_type == IS_CONST) {
goto optimize_constant_binary_op;
}
if (opline->op1_type == IS_CONST &&
(Z_TYPE(ZEND_OP1_LITERAL(opline)) <= IS_TRUE && Z_TYPE(ZEND_OP1_LITERAL(opline)) >= IS_NULL)) {
/* IS_IDENTICAL(TRUE, T) => TYPE_CHECK(T, TRUE)
* IS_IDENTICAL(FALSE, T) => TYPE_CHECK(T, FALSE)
* IS_IDENTICAL(NULL, T) => TYPE_CHECK(T, NULL)
*/
opline->opcode = ZEND_TYPE_CHECK;
opline->extended_value = (1 << Z_TYPE(ZEND_OP1_LITERAL(opline)));
COPY_NODE(opline->op1, opline->op2);
SET_UNUSED(opline->op2);
++(*opt_count);
goto optimize_type_check;
} else if (opline->op2_type == IS_CONST &&
(Z_TYPE(ZEND_OP2_LITERAL(opline)) <= IS_TRUE && Z_TYPE(ZEND_OP2_LITERAL(opline)) >= IS_NULL)) {
/* IS_IDENTICAL(T, TRUE) => TYPE_CHECK(T, TRUE)
* IS_IDENTICAL(T, FALSE) => TYPE_CHECK(T, FALSE)
* IS_IDENTICAL(T, NULL) => TYPE_CHECK(T, NULL)
*/
opline->opcode = ZEND_TYPE_CHECK;
opline->extended_value = (1 << Z_TYPE(ZEND_OP2_LITERAL(opline)));
SET_UNUSED(opline->op2);
++(*opt_count);
goto optimize_type_check;
}
break;
case ZEND_TYPE_CHECK:
optimize_type_check:
if (opline->extended_value == (1 << IS_TRUE) || opline->extended_value == (1 << IS_FALSE)) {
if (opline->op1_type == IS_TMP_VAR &&
!zend_bitset_in(used_ext, VAR_NUM(opline->op1.var))) {
src = VAR_SOURCE(opline->op1);
if (src) {
switch (src->opcode) {
case ZEND_BOOL:
case ZEND_BOOL_NOT:
/* T = BOOL(X) + TYPE_CHECK(T, TRUE) -> BOOL(X), NOP
* T = BOOL(X) + TYPE_CHECK(T, FALSE) -> BOOL_NOT(X), NOP
* T = BOOL_NOT(X) + TYPE_CHECK(T, TRUE) -> BOOL_NOT(X), NOP
* T = BOOL_NOT(X) + TYPE_CHECK(T, FALSE) -> BOOL(X), NOP
*/
src->opcode =
((src->opcode == ZEND_BOOL) == (opline->extended_value == (1 << IS_TRUE))) ?
ZEND_BOOL : ZEND_BOOL_NOT;
COPY_NODE(src->result, opline->result);
SET_VAR_SOURCE(src);
MAKE_NOP(opline);
++(*opt_count);
break;
}
}
}
}
break;
case ZEND_BOOL:
case ZEND_BOOL_NOT:
optimize_bool:
@ -871,6 +801,7 @@ optimize_type_check:
case ZEND_SR:
case ZEND_IS_SMALLER:
case ZEND_IS_SMALLER_OR_EQUAL:
case ZEND_IS_IDENTICAL:
case ZEND_IS_NOT_IDENTICAL:
case ZEND_BOOL_XOR:
case ZEND_BW_OR:
@ -937,6 +868,7 @@ optimize_const_unary_op:
break;
case ZEND_RETURN:
case ZEND_EXIT:
if (opline->op1_type == IS_TMP_VAR) {
src = VAR_SOURCE(opline->op1);
if (src && src->opcode == ZEND_QM_ASSIGN) {
@ -1085,7 +1017,6 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op
case ZEND_ASSERT_CHECK:
case ZEND_JMP_NULL:
case ZEND_BIND_INIT_STATIC_OR_JMP:
case ZEND_JMP_FRAMELESS:
ZEND_SET_OP_JMP_ADDR(opline, opline->op2, new_opcodes + blocks[b->successors[0]].start);
break;
case ZEND_CATCH:
@ -1289,7 +1220,8 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr
target = op_array->opcodes + target_block->start;
if ((target->opcode == ZEND_RETURN ||
target->opcode == ZEND_RETURN_BY_REF ||
target->opcode == ZEND_GENERATOR_RETURN) &&
target->opcode == ZEND_GENERATOR_RETURN ||
target->opcode == ZEND_EXIT) &&
!(op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) {
/* JMP L, L: RETURN to immediate RETURN */
*last_op = *target;

View file

@ -43,6 +43,50 @@ typedef struct _literal_info {
info[n].num_related = (related); \
} while (0)
static size_t type_num_classes(const zend_op_array *op_array, uint32_t arg_num)
{
zend_arg_info *arg_info;
if (arg_num > 0) {
if (!(op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) {
return 0;
}
if (EXPECTED(arg_num <= op_array->num_args)) {
arg_info = &op_array->arg_info[arg_num-1];
} else if (UNEXPECTED(op_array->fn_flags & ZEND_ACC_VARIADIC)) {
arg_info = &op_array->arg_info[op_array->num_args];
} else {
return 0;
}
} else {
arg_info = op_array->arg_info - 1;
}
if (ZEND_TYPE_IS_COMPLEX(arg_info->type)) {
if (ZEND_TYPE_HAS_LIST(arg_info->type)) {
/* Intersection types cannot have nested list types */
if (ZEND_TYPE_IS_INTERSECTION(arg_info->type)) {
return ZEND_TYPE_LIST(arg_info->type)->num_types;
}
ZEND_ASSERT(ZEND_TYPE_IS_UNION(arg_info->type));
size_t count = 0;
zend_type *list_type;
ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(arg_info->type), list_type) {
if (ZEND_TYPE_IS_INTERSECTION(*list_type)) {
count += ZEND_TYPE_LIST(*list_type)->num_types;
} else {
ZEND_ASSERT(!ZEND_TYPE_HAS_LIST(*list_type));
count += 1;
}
} ZEND_TYPE_LIST_FOREACH_END();
return count;
}
return 1;
}
return 0;
}
static uint32_t add_static_slot(HashTable *hash,
zend_op_array *op_array,
uint32_t op1,
@ -121,7 +165,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
HashTable hash;
zend_string *key = NULL;
void *checkpoint = zend_arena_checkpoint(ctx->arena);
int *const_slot, *class_slot, *func_slot, *bind_var_slot, *property_slot, *method_slot, *jmp_slot;
int *const_slot, *class_slot, *func_slot, *bind_var_slot, *property_slot, *method_slot;
if (op_array->last_literal) {
info = (literal_info*)zend_arena_calloc(&ctx->arena, op_array->last_literal, sizeof(literal_info));
@ -131,9 +175,6 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
end = opline + op_array->last;
while (opline < end) {
switch (opline->opcode) {
case ZEND_JMP_FRAMELESS:
LITERAL_INFO(opline->op1.constant, 1);
break;
case ZEND_INIT_FCALL_BY_NAME:
LITERAL_INFO(opline->op2.constant, 2);
break;
@ -156,9 +197,6 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
LITERAL_INFO(opline->op2.constant, 2);
}
break;
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:
LITERAL_INFO(opline->op1.constant, 1);
break;
case ZEND_CATCH:
LITERAL_INFO(opline->op1.constant, 2);
break;
@ -439,14 +477,13 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
zend_hash_clean(&hash);
op_array->last_literal = j;
const_slot = zend_arena_alloc(&ctx->arena, j * 7 * sizeof(int));
memset(const_slot, -1, j * 7 * sizeof(int));
const_slot = zend_arena_alloc(&ctx->arena, j * 6 * sizeof(int));
memset(const_slot, -1, j * 6 * sizeof(int));
class_slot = const_slot + j;
func_slot = class_slot + j;
bind_var_slot = func_slot + j;
property_slot = bind_var_slot + j;
method_slot = property_slot + j;
jmp_slot = method_slot + j;
/* Update opcodes to use new literals table */
cache_size = zend_op_array_extension_handles * sizeof(void*);
@ -460,6 +497,26 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
opline->op2.constant = map[opline->op2.constant];
}
switch (opline->opcode) {
case ZEND_RECV_INIT:
case ZEND_RECV:
case ZEND_RECV_VARIADIC:
{
size_t num_classes = type_num_classes(op_array, opline->op1.num);
if (num_classes) {
opline->extended_value = cache_size;
cache_size += num_classes * sizeof(void *);
}
break;
}
case ZEND_VERIFY_RETURN_TYPE:
{
size_t num_classes = type_num_classes(op_array, 0);
if (num_classes) {
opline->op2.num = cache_size;
cache_size += num_classes * sizeof(void *);
}
break;
}
case ZEND_ASSIGN_STATIC_PROP_OP:
if (opline->op1_type == IS_CONST) {
// op1 static property
@ -716,16 +773,6 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
opline->extended_value = cache_size;
cache_size += sizeof(void *);
break;
case ZEND_JMP_FRAMELESS:
// op1 func
if (jmp_slot[opline->op1.constant] >= 0) {
opline->extended_value = jmp_slot[opline->op1.constant];
} else {
opline->extended_value = cache_size;
cache_size += sizeof(void *);
jmp_slot[opline->op1.constant] = opline->extended_value;
}
break;
case ZEND_SEND_VAL:
case ZEND_SEND_VAL_EX:
case ZEND_SEND_VAR:

View file

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

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);
}
static bool safe_instanceof(const zend_class_entry *ce1, const zend_class_entry *ce2) {
static bool safe_instanceof(zend_class_entry *ce1, zend_class_entry *ce2) {
if (ce1 == ce2) {
return 1;
}
@ -267,9 +267,9 @@ static bool safe_instanceof(const zend_class_entry *ce1, const zend_class_entry
static inline bool can_elide_list_type(
const zend_script *script, const zend_op_array *op_array,
const zend_ssa_var_info *use_info, const zend_type type)
const zend_ssa_var_info *use_info, zend_type type)
{
const zend_type *single_type;
zend_type *single_type;
/* For intersection: result==false is failure, default is success.
* For union: result==true is success, default is failure. */
bool is_intersection = ZEND_TYPE_IS_INTERSECTION(type);
@ -280,7 +280,7 @@ static inline bool can_elide_list_type(
}
if (ZEND_TYPE_HAS_NAME(*single_type)) {
zend_string *lcname = zend_string_tolower(ZEND_TYPE_NAME(*single_type));
const zend_class_entry *ce = zend_optimizer_get_class_entry(script, op_array, lcname);
zend_class_entry *ce = zend_optimizer_get_class_entry(script, op_array, lcname);
zend_string_release(lcname);
bool result = ce && safe_instanceof(use_info->ce, ce);
if (result == !is_intersection) {
@ -325,19 +325,6 @@ static bool opline_supports_assign_contraction(
return 0;
}
/* Frameless calls override the return value, but the return value may overlap with the arguments. */
switch (opline->opcode) {
case ZEND_FRAMELESS_ICALL_3:
if ((opline + 1)->op1_type == IS_CV && (opline + 1)->op1.var == cv_var) return 0;
ZEND_FALLTHROUGH;
case ZEND_FRAMELESS_ICALL_2:
if (opline->op2_type == IS_CV && opline->op2.var == cv_var) return 0;
ZEND_FALLTHROUGH;
case ZEND_FRAMELESS_ICALL_1:
if (opline->op1_type == IS_CV && opline->op1.var == cv_var) return 0;
return 1;
}
if (opline->opcode == ZEND_DO_ICALL || opline->opcode == ZEND_DO_UCALL
|| opline->opcode == ZEND_DO_FCALL || opline->opcode == ZEND_DO_FCALL_BY_NAME) {
/* Function calls may dtor the return value after it has already been written -- allow
@ -407,28 +394,40 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa)
zend_call_info *call_info = func_info->callee_info;
do {
zend_op *op = call_info->caller_init_opline;
if ((op->opcode == ZEND_FRAMELESS_ICALL_2
|| (op->opcode == ZEND_FRAMELESS_ICALL_3 && (op + 1)->op1_type == IS_CONST))
if (call_info->caller_call_opline
&& call_info->caller_call_opline->opcode == ZEND_DO_ICALL
&& call_info->callee_func
&& zend_string_equals_literal_ci(call_info->callee_func->common.function_name, "in_array")) {
&& zend_string_equals_literal(call_info->callee_func->common.function_name, "in_array")
&& (call_info->caller_init_opline->extended_value == 2
|| (call_info->caller_init_opline->extended_value == 3
&& (call_info->caller_call_opline - 1)->opcode == ZEND_SEND_VAL
&& (call_info->caller_call_opline - 1)->op1_type == IS_CONST))) {
zend_op *send_array;
zend_op *send_needly;
bool strict = 0;
bool has_opdata = op->opcode == ZEND_FRAMELESS_ICALL_3;
ZEND_ASSERT(!call_info->is_prototype);
if (has_opdata) {
if (zend_is_true(CT_CONSTANT_EX(op_array, (op + 1)->op1.constant))) {
if (call_info->caller_init_opline->extended_value == 2) {
send_array = call_info->caller_call_opline - 1;
send_needly = call_info->caller_call_opline - 2;
} else {
if (zend_is_true(CT_CONSTANT_EX(op_array, (call_info->caller_call_opline - 1)->op1.constant))) {
strict = 1;
}
send_array = call_info->caller_call_opline - 2;
send_needly = call_info->caller_call_opline - 3;
}
if (op->op2_type == IS_CONST
&& Z_TYPE_P(CT_CONSTANT_EX(op_array, op->op2.constant)) == IS_ARRAY) {
if (send_array->opcode == ZEND_SEND_VAL
&& send_array->op1_type == IS_CONST
&& Z_TYPE_P(CT_CONSTANT_EX(op_array, send_array->op1.constant)) == IS_ARRAY
&& (send_needly->opcode == ZEND_SEND_VAL
|| send_needly->opcode == ZEND_SEND_VAR)
) {
bool ok = 1;
HashTable *src = Z_ARRVAL_P(CT_CONSTANT_EX(op_array, op->op2.constant));
HashTable *src = Z_ARRVAL_P(CT_CONSTANT_EX(op_array, send_array->op1.constant));
HashTable *dst;
zval *val, tmp;
zend_ulong idx;
@ -459,15 +458,59 @@ int zend_dfa_optimize_calls(zend_op_array *op_array, zend_ssa *ssa)
}
if (ok) {
uint32_t op_num = send_needly - op_array->opcodes;
zend_ssa_op *ssa_op = ssa->ops + op_num;
if (ssa_op->op1_use >= 0) {
/* Reconstruct SSA */
int var_num = ssa_op->op1_use;
zend_ssa_var *var = ssa->vars + var_num;
ZEND_ASSERT(ssa_op->op1_def < 0);
zend_ssa_unlink_use_chain(ssa, op_num, ssa_op->op1_use);
ssa_op->op1_use = -1;
ssa_op->op1_use_chain = -1;
op_num = call_info->caller_call_opline - op_array->opcodes;
ssa_op = ssa->ops + op_num;
ssa_op->op1_use = var_num;
ssa_op->op1_use_chain = var->use_chain;
var->use_chain = op_num;
}
ZVAL_ARR(&tmp, dst);
/* Update opcode */
op->opcode = ZEND_IN_ARRAY;
op->extended_value = strict;
op->op2.constant = zend_optimizer_add_literal(op_array, &tmp);
if (has_opdata) {
MAKE_NOP(op + 1);
removed_ops++;
call_info->caller_call_opline->opcode = ZEND_IN_ARRAY;
call_info->caller_call_opline->extended_value = strict;
call_info->caller_call_opline->op1_type = send_needly->op1_type;
call_info->caller_call_opline->op1.num = send_needly->op1.num;
call_info->caller_call_opline->op2_type = IS_CONST;
call_info->caller_call_opline->op2.constant = zend_optimizer_add_literal(op_array, &tmp);
if (call_info->caller_init_opline->extended_value == 3) {
MAKE_NOP(call_info->caller_call_opline - 1);
}
MAKE_NOP(call_info->caller_init_opline);
MAKE_NOP(send_needly);
MAKE_NOP(send_array);
removed_ops++;
op_num = call_info->caller_call_opline - op_array->opcodes;
ssa_op = ssa->ops + op_num;
if (ssa_op->result_def >= 0) {
int var = ssa_op->result_def;
int use = ssa->vars[var].use_chain;
/* If the result is used only in a JMPZ/JMPNZ, replace result type with
* IS_TMP_VAR, which will enable use of smart branches. Don't do this
* in other cases, as not all opcodes support both VAR and TMP. */
if (ssa->vars[var].phi_use_chain == NULL
&& ssa->ops[use].op1_use == var
&& ssa->ops[use].op1_use_chain == -1
&& (op_array->opcodes[use].opcode == ZEND_JMPZ
|| op_array->opcodes[use].opcode == ZEND_JMPNZ)) {
call_info->caller_call_opline->result_type = IS_TMP_VAR;
op_array->opcodes[use].op1_type = IS_TMP_VAR;
}
}
}
}
@ -610,7 +653,6 @@ static void zend_ssa_replace_control_link(zend_op_array *op_array, zend_ssa *ssa
case ZEND_ASSERT_CHECK:
case ZEND_JMP_NULL:
case ZEND_BIND_INIT_STATIC_OR_JMP:
case ZEND_JMP_FRAMELESS:
if (ZEND_OP2_JMP_ADDR(opline) == op_array->opcodes + old->start) {
ZEND_SET_OP_JMP_ADDR(opline, opline->op2, op_array->opcodes + dst->start);
}
@ -965,7 +1007,7 @@ optimize_nop:
static bool zend_dfa_try_to_replace_result(zend_op_array *op_array, zend_ssa *ssa, int def, int cv_var)
{
int result_var = ssa->ops[def].result_def;
uint32_t cv = EX_NUM_TO_VAR(ssa->vars[cv_var].var);
int cv = EX_NUM_TO_VAR(ssa->vars[cv_var].var);
if (result_var >= 0
&& !(ssa->var_info[cv_var].type & MAY_BE_REF)

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_METHOD_CALL:
case ZEND_INIT_FCALL:
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:
if (call == 0) {
MAKE_NOP(opline);
return;
@ -78,10 +77,8 @@ static void zend_delete_call_instructions(zend_op_array *op_array, zend_op *opli
static void zend_try_inline_call(zend_op_array *op_array, zend_op *fcall, zend_op *opline, zend_function *func)
{
const uint32_t no_discard = RETURN_VALUE_USED(opline) ? 0 : ZEND_ACC_NODISCARD;
if (func->type == ZEND_USER_FUNCTION
&& !(func->op_array.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_HAS_TYPE_HINTS|ZEND_ACC_DEPRECATED|no_discard))
&& !(func->op_array.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_HAS_TYPE_HINTS))
/* TODO: function copied from trait may be inconsistent ??? */
&& !(func->op_array.fn_flags & (ZEND_ACC_TRAIT_CLONE))
&& fcall->extended_value >= func->op_array.required_num_args
@ -172,15 +169,12 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
case ZEND_INIT_METHOD_CALL:
case ZEND_INIT_FCALL:
case ZEND_NEW:
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:
/* The argument passing optimizations are valid for prototypes as well,
* as inheritance cannot change between ref <-> non-ref arguments. */
call_stack[call].func = zend_optimizer_get_called_func(
ctx->script, op_array, opline, &call_stack[call].is_prototype);
call_stack[call].try_inline =
!call_stack[call].is_prototype
&& opline->opcode != ZEND_NEW
&& opline->opcode != ZEND_INIT_PARENT_PROPERTY_HOOK_CALL;
!call_stack[call].is_prototype && opline->opcode != ZEND_NEW;
ZEND_FALLTHROUGH;
case ZEND_INIT_DYNAMIC_CALL:
case ZEND_INIT_USER_CALL:
@ -204,31 +198,26 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func);
literal_dtor(&ZEND_OP2_LITERAL(fcall));
fcall->op2.constant = fcall->op2.constant + 1;
if (opline->opcode != ZEND_CALLABLE_CONVERT) {
opline->opcode = zend_get_call_op(fcall, call_stack[call].func);
}
} else if (fcall->opcode == ZEND_INIT_NS_FCALL_BY_NAME) {
fcall->opcode = ZEND_INIT_FCALL;
fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func);
literal_dtor(&op_array->literals[fcall->op2.constant]);
literal_dtor(&op_array->literals[fcall->op2.constant + 2]);
fcall->op2.constant = fcall->op2.constant + 1;
if (opline->opcode != ZEND_CALLABLE_CONVERT) {
opline->opcode = zend_get_call_op(fcall, call_stack[call].func);
}
} else if (fcall->opcode == ZEND_INIT_STATIC_METHOD_CALL
|| fcall->opcode == ZEND_INIT_METHOD_CALL
|| fcall->opcode == ZEND_INIT_PARENT_PROPERTY_HOOK_CALL
|| fcall->opcode == ZEND_NEW) {
/* We don't have specialized opcodes for this, do nothing */
} else {
ZEND_UNREACHABLE();
}
/* If the INIT opcode changed the DO opcode can also change to
* a more optimized one.
*
* At this point we also know whether or not the result of
* the DO opcode is used, allowing to optimize calls to
* ZEND_ACC_NODISCARD functions. */
if (opline->opcode != ZEND_CALLABLE_CONVERT) {
opline->opcode = zend_get_call_op(fcall, call_stack[call].func, !RESULT_UNUSED(opline));
}
if ((ZEND_OPTIMIZER_PASS_16 & ctx->optimization_level)
&& call_stack[call].try_inline
&& opline->opcode != ZEND_CALLABLE_CONVERT) {

View file

@ -161,26 +161,33 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
}
break;
case ZEND_FETCH_CLASS_CONSTANT: {
bool is_prototype;
const zend_class_constant *cc = zend_fetch_class_const_info(ctx->script, op_array, opline, &is_prototype);
if (!cc || is_prototype) {
break;
}
const zval *c = &cc->value;
if (Z_TYPE_P(c) == IS_CONSTANT_AST) {
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;
case ZEND_FETCH_CLASS_CONSTANT:
if (opline->op2_type == IS_CONST &&
Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) {
zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1(
ctx->script, op_array, opline);
if (ce) {
zend_class_constant *cc = zend_hash_find_ptr(
&ce->constants_table, Z_STR(ZEND_OP2_LITERAL(opline)));
if (cc && !(ZEND_CLASS_CONST_FLAGS(cc) & ZEND_ACC_DEPRECATED) && (ZEND_CLASS_CONST_FLAGS(cc) & ZEND_ACC_PPP_MASK) == ZEND_ACC_PUBLIC && !(ce->ce_flags & ZEND_ACC_TRAIT)) {
zval *c = &cc->value;
if (Z_TYPE_P(c) == IS_CONSTANT_AST) {
zend_ast *ast = Z_ASTVAL_P(c);
if (ast->kind != ZEND_AST_CONSTANT
|| !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;
}
case ZEND_DO_ICALL: {
zend_op *send1_opline = opline - 1;
@ -315,7 +322,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
case ZEND_JMPZ:
case ZEND_JMPNZ:
if (opline->op1_type == IS_CONST) {
bool should_jmp = zend_is_true(&ZEND_OP1_LITERAL(opline));
int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(opline));
if (opline->opcode == ZEND_JMPZ) {
should_jmp = !should_jmp;
@ -337,6 +344,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
case ZEND_RETURN:
case ZEND_RETURN_BY_REF:
case ZEND_GENERATOR_RETURN:
case ZEND_EXIT:
case ZEND_THROW:
case ZEND_MATCH_ERROR:
case ZEND_CATCH:
@ -353,7 +361,6 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
case ZEND_JMP_NULL:
case ZEND_VERIFY_NEVER_TYPE:
case ZEND_BIND_INIT_STATIC_OR_JMP:
case ZEND_JMP_FRAMELESS:
collect_constants = 0;
break;
}

View file

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

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,
* or just happened to be commonly used with constant operands in WP (need to test other
* applications as well, of course). */
static inline zend_result ct_eval_func_call_ex(
zend_op_array *op_array, zval *result, zend_function *func, uint32_t num_args, zval **args) {
static inline zend_result ct_eval_func_call(
zend_op_array *op_array, zval *result, zend_string *name, uint32_t num_args, zval **args) {
uint32_t i;
zend_string *name = func->common.function_name;
zend_function *func = zend_hash_find_ptr(CG(function_table), name);
if (!func || func->type != ZEND_INTERNAL_FUNCTION) {
return FAILURE;
}
if (num_args == 1 && Z_TYPE_P(args[0]) == IS_STRING &&
zend_optimizer_eval_special_func_call(result, name, Z_STR_P(args[0])) == SUCCESS) {
return SUCCESS;
@ -851,15 +855,6 @@ static inline zend_result ct_eval_func_call_ex(
return retval;
}
static inline zend_result ct_eval_func_call(
zend_op_array *op_array, zval *result, zend_string *name, uint32_t num_args, zval **args) {
zend_function *func = zend_hash_find_ptr(CG(function_table), name);
if (!func || func->type != ZEND_INTERNAL_FUNCTION) {
return FAILURE;
}
return ct_eval_func_call_ex(op_array, result, func, num_args, args);
}
#define SET_RESULT(op, zv) do { \
if (ssa_op->op##_def >= 0) { \
set_value(scdf, ctx, ssa_op->op##_def, zv); \
@ -1713,51 +1708,6 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
SET_RESULT_BOT(result);
break;
}
case ZEND_FRAMELESS_ICALL_0:
case ZEND_FRAMELESS_ICALL_1:
case ZEND_FRAMELESS_ICALL_2:
case ZEND_FRAMELESS_ICALL_3: {
/* We already know it can't be evaluated, don't bother checking again */
if (ssa_op->result_def < 0 || IS_BOT(&ctx->values[ssa_op->result_def])) {
break;
}
zval *args[3] = {NULL};
zend_function *func = ZEND_FLF_FUNC(opline);
uint32_t num_args = ZEND_FLF_NUM_ARGS(opline->opcode);
switch (num_args) {
case 3: {
zend_op *op_data = opline + 1;
args[2] = get_op1_value(ctx, op_data, &ctx->scdf.ssa->ops[op_data - ctx->scdf.op_array->opcodes]);
ZEND_FALLTHROUGH;
}
case 2:
args[1] = get_op2_value(ctx, opline, &ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes]);
ZEND_FALLTHROUGH;
case 1:
args[0] = get_op1_value(ctx, opline, &ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes]);
break;
}
for (uint32_t i = 0; i < num_args; i++) {
if (!args[i]) {
SET_RESULT_BOT(result);
return;
} else if (IS_BOT(args[i]) || IS_PARTIAL_ARRAY(args[i])) {
SET_RESULT_BOT(result);
return;
} else if (IS_TOP(args[i])) {
return;
}
}
if (ct_eval_func_call_ex(scdf->op_array, &zv, func, num_args, args) == SUCCESS) {
SET_RESULT(result, &zv);
zval_ptr_dtor_nogc(&zv);
break;
}
SET_RESULT_BOT(result);
break;
}
default:
{
/* If we have no explicit implementation return BOT */
@ -2205,13 +2155,7 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var,
if (opline->opcode == ZEND_DO_ICALL) {
removed_ops = remove_call(ctx, opline, ssa_op) - 1;
} else {
bool has_op_data = opline->opcode == ZEND_FRAMELESS_ICALL_3;
zend_ssa_remove_instr(ssa, opline, ssa_op);
removed_ops++;
if (has_op_data) {
zend_ssa_remove_instr(ssa, opline + 1, ssa_op + 1);
removed_ops++;
}
}
ssa_op->result_def = var_num;
opline->opcode = ZEND_QM_ASSIGN;
@ -2247,13 +2191,8 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var,
if (opline->opcode == ZEND_DO_ICALL) {
removed_ops = remove_call(ctx, opline, ssa_op);
} else {
bool has_op_data = opline->opcode == ZEND_FRAMELESS_ICALL_3;
zend_ssa_remove_instr(ssa, opline, ssa_op);
removed_ops++;
if (has_op_data) {
zend_ssa_remove_instr(ssa, opline + 1, ssa_op + 1);
removed_ops++;
}
}
}
} else if (ssa_op->op1_def == var_num) {

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_METHOD_CALL:
case ZEND_INIT_STATIC_METHOD_CALL:
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL:
call_stack[call] = call_info;
func = zend_optimizer_get_called_func(
script, op_array, opline, &is_prototype);
@ -74,13 +73,11 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32
call_info->num_args = opline->extended_value;
call_info->next_callee = func_info->callee_info;
call_info->is_prototype = is_prototype;
call_info->is_frameless = false;
func_info->callee_info = call_info;
if (build_flags & ZEND_CALL_TREE) {
call_info->next_caller = NULL;
} else if (func->type == ZEND_INTERNAL_FUNCTION
|| func->op_array.filename != script->filename) {
} else if (func->type == ZEND_INTERNAL_FUNCTION) {
call_info->next_caller = NULL;
} else {
zend_func_info *callee_func_info = ZEND_FUNC_INFO(&func->op_array);
@ -105,24 +102,6 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32
call_info = NULL;
call++;
break;
case ZEND_FRAMELESS_ICALL_0:
case ZEND_FRAMELESS_ICALL_1:
case ZEND_FRAMELESS_ICALL_2:
case ZEND_FRAMELESS_ICALL_3: {
func = ZEND_FLF_FUNC(opline);
zend_call_info *call_info = zend_arena_calloc(arena, 1, sizeof(zend_call_info));
call_info->caller_op_array = op_array;
call_info->caller_init_opline = opline;
call_info->caller_call_opline = NULL;
call_info->callee_func = func;
call_info->num_args = ZEND_FLF_NUM_ARGS(opline->opcode);
call_info->next_callee = func_info->callee_info;
call_info->is_prototype = false;
call_info->is_frameless = true;
call_info->next_caller = NULL;
func_info->callee_info = call_info;
break;
}
case ZEND_DO_FCALL:
case ZEND_DO_ICALL:
case ZEND_DO_UCALL:
@ -163,6 +142,10 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32
call_info->send_unpack = 1;
}
break;
case ZEND_EXIT:
/* In this case the DO_CALL opcode may have been dropped
* and caller_call_opline will be NULL. */
break;
}
opline++;
}
@ -277,11 +260,9 @@ ZEND_API zend_call_info **zend_build_call_map(zend_arena **arena, zend_func_info
if (call->caller_call_opline) {
map[call->caller_call_opline - op_array->opcodes] = call;
}
if (!call->is_frameless) {
for (i = 0; i < call->num_args; i++) {
if (call->arg_info[i].opline) {
map[call->arg_info[i].opline - op_array->opcodes] = call;
}
for (i = 0; i < call->num_args; i++) {
if (call->arg_info[i].opline) {
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 named_args; /* Function has named arguments */
bool is_prototype; /* An overridden child method may be called */
bool is_frameless; /* A frameless function sends arguments through operands */
int num_args; /* Number of arguments, excluding named and variadic arguments */
zend_send_arg_info arg_info[1];
};

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_worklist work;
ALLOCA_FLAG(list_use_heap)
ZEND_WORKLIST_ALLOCA(&work, cfg->blocks_count, list_use_heap);
zend_worklist_push(&work, b - cfg->blocks);
while (zend_worklist_len(&work)) {
while (1) {
int i;
b = cfg->blocks + zend_worklist_pop(&work);
b->flags |= ZEND_BB_REACHABLE;
if (b->successors_count == 0) {
b->flags |= ZEND_BB_EXIT;
continue;
return;
}
for (i = 0; i < b->successors_count; i++) {
@ -93,14 +86,22 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc
succ->flags |= ZEND_BB_FOLLOW;
}
/* Check reachability of successor */
if (!(succ->flags & ZEND_BB_REACHABLE)) {
zend_worklist_push(&work, succ - cfg->blocks);
if (i == b->successors_count - 1) {
/* Tail call optimization */
if (succ->flags & ZEND_BB_REACHABLE) {
return;
}
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;
case ZEND_MATCH_ERROR:
case ZEND_EXIT:
case ZEND_THROW:
/* Don't treat THROW as terminator if it's used in expression context,
* as we may lose live ranges when eliminating unreachable code. */
@ -372,7 +374,6 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array,
case ZEND_ASSERT_CHECK:
case ZEND_JMP_NULL:
case ZEND_BIND_INIT_STATIC_OR_JMP:
case ZEND_JMP_FRAMELESS:
BB_START(OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes);
BB_START(i + 1);
break;
@ -509,6 +510,7 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array,
case ZEND_RETURN:
case ZEND_RETURN_BY_REF:
case ZEND_GENERATOR_RETURN:
case ZEND_EXIT:
case ZEND_THROW:
case ZEND_MATCH_ERROR:
case ZEND_VERIFY_NEVER_TYPE:
@ -526,7 +528,6 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array,
case ZEND_ASSERT_CHECK:
case ZEND_JMP_NULL:
case ZEND_BIND_INIT_STATIC_OR_JMP:
case ZEND_JMP_FRAMELESS:
block->successors_count = 2;
block->successors[0] = block_map[OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes];
block->successors[1] = j + 1;

View file

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

View file

@ -23,7 +23,7 @@
#include "zend_func_info.h"
#include "zend_call_graph.h"
#include "zend_dump.h"
#include "zend_smart_str.h"
#include "ext/standard/php_string.h"
void zend_dump_ht(HashTable *ht)
{
@ -66,27 +66,13 @@ void zend_dump_const(const zval *zv)
case IS_DOUBLE:
fprintf(stderr, " float(%g)", Z_DVAL_P(zv));
break;
case IS_STRING: {
smart_str escaped_string = {0};
smart_str_append_escaped(&escaped_string, Z_STRVAL_P(zv), Z_STRLEN_P(zv));
smart_str_0(&escaped_string);
case IS_STRING:;
zend_string *escaped_string = php_addcslashes(Z_STR_P(zv), "\"\\", 2);
fprintf(stderr, " string(\"");
fprintf(stderr, " string(\"%s\")", ZSTR_VAL(escaped_string));
/* Also escape '"' */
for (size_t i = 0; i < ZSTR_LEN(escaped_string.s); i++) {
if (ZSTR_VAL(escaped_string.s)[i] == '"') {
fprintf(stderr, "\\\"");
} else {
putc(ZSTR_VAL(escaped_string.s)[i], stderr);
}
}
fprintf(stderr, "\")");
smart_str_free_ex(&escaped_string, false);
zend_string_release(escaped_string);
break;
}
case IS_ARRAY:
fprintf(stderr, " array(...)");
break;
@ -151,7 +137,7 @@ static void zend_dump_unused_op(const zend_op *opline, znode_op op, uint32_t fla
}
}
ZEND_API void zend_dump_var(const zend_op_array *op_array, uint8_t var_type, uint32_t var_num)
ZEND_API void zend_dump_var(const zend_op_array *op_array, uint8_t var_type, int var_num)
{
if (var_type == IS_CV && var_num < op_array->last_var) {
fprintf(stderr, "CV%d($%s)", var_num, op_array->vars[var_num]->val);
@ -380,7 +366,7 @@ static void zend_dump_ssa_var_info(const zend_ssa *ssa, int ssa_var_num, uint32_
dump_flags);
}
ZEND_API void zend_dump_ssa_var(const zend_op_array *op_array, const zend_ssa *ssa, int ssa_var_num, uint8_t var_type, uint32_t var_num, uint32_t dump_flags)
ZEND_API void zend_dump_ssa_var(const zend_op_array *op_array, const zend_ssa *ssa, int ssa_var_num, uint8_t var_type, int var_num, uint32_t dump_flags)
{
if (ssa_var_num >= 0) {
fprintf(stderr, "#%d.", ssa_var_num);
@ -477,11 +463,6 @@ ZEND_API void zend_dump_op(const zend_op_array *op_array, const zend_basic_block
fprintf(stderr, "OP_%d", (int)opline->opcode);
}
if (ZEND_OP_IS_FRAMELESS_ICALL(opline->opcode)) {
zend_function *func = ZEND_FLF_FUNC(opline);
fprintf(stderr, "(%s)", ZSTR_VAL(func->common.function_name));
}
if (ZEND_VM_EXT_NUM == (flags & ZEND_VM_EXT_MASK)) {
fprintf(stderr, " %u", opline->extended_value);
} else if (ZEND_VM_EXT_OP == (flags & ZEND_VM_EXT_MASK)) {
@ -943,6 +924,7 @@ void zend_dump_op_array_name(const zend_op_array *op_array)
ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, const char *msg, const void *data)
{
int i;
const zend_cfg *cfg = NULL;
const zend_ssa *ssa = NULL;
zend_func_info *func_info = NULL;
@ -1028,7 +1010,7 @@ ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_fl
}
if (ssa && ssa->var_info) {
for (uint32_t i = 0; i < op_array->last_var; i++) {
for (i = 0; i < op_array->last_var; i++) {
fprintf(stderr, " ; ");
zend_dump_ssa_var(op_array, ssa, i, IS_CV, i, dump_flags);
fprintf(stderr, "\n");
@ -1056,7 +1038,7 @@ ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_fl
}
if (op_array->last_live_range && (dump_flags & ZEND_DUMP_LIVE_RANGES)) {
fprintf(stderr, "LIVE RANGES:\n");
for (int i = 0; i < op_array->last_live_range; i++) {
for (i = 0; i < op_array->last_live_range; i++) {
fprintf(stderr,
" %u: %04u - %04u ",
EX_VAR_TO_NUM(op_array->live_range[i].var & ~ZEND_LIVE_MASK),
@ -1083,7 +1065,7 @@ ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_fl
}
if (op_array->last_try_catch) {
fprintf(stderr, "EXCEPTION TABLE:\n");
for (int i = 0; i < op_array->last_try_catch; i++) {
for (i = 0; i < op_array->last_try_catch; i++) {
fprintf(stderr, " BB%u",
cfg->map[op_array->try_catch_array[i].try_op]);
if (op_array->try_catch_array[i].catch_op) {
@ -1116,7 +1098,7 @@ ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_fl
}
if (op_array->last_live_range && (dump_flags & ZEND_DUMP_LIVE_RANGES)) {
fprintf(stderr, "LIVE RANGES:\n");
for (int i = 0; i < op_array->last_live_range; i++) {
for (i = 0; i < op_array->last_live_range; i++) {
fprintf(stderr,
" %u: %04u - %04u ",
EX_VAR_TO_NUM(op_array->live_range[i].var & ~ZEND_LIVE_MASK),
@ -1143,7 +1125,7 @@ ZEND_API void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_fl
}
if (op_array->last_try_catch) {
fprintf(stderr, "EXCEPTION TABLE:\n");
for (int i = 0; i < op_array->last_try_catch; i++) {
for (i = 0; i < op_array->last_try_catch; i++) {
fprintf(stderr,
" %04u",
op_array->try_catch_array[i].try_op);
@ -1189,6 +1171,20 @@ void zend_dump_dominators(const zend_op_array *op_array, const zend_cfg *cfg)
}
}
void zend_dump_variables(const zend_op_array *op_array)
{
int j;
fprintf(stderr, "\nCV Variables for \"");
zend_dump_op_array_name(op_array);
fprintf(stderr, "\"\n");
for (j = 0; j < op_array->last_var; j++) {
fprintf(stderr, " ");
zend_dump_var(op_array, IS_CV, j);
fprintf(stderr, "\n");
}
}
void zend_dump_ssa_variables(const zend_op_array *op_array, const zend_ssa *ssa, uint32_t dump_flags)
{
int j;

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_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const zend_dfg *dfg);
void zend_dump_phi_placement(const zend_op_array *op_array, const zend_ssa *ssa);
void zend_dump_variables(const zend_op_array *op_array);
void zend_dump_ssa_variables(const zend_op_array *op_array, const zend_ssa *ssa, uint32_t dump_flags);
ZEND_API void zend_dump_ssa_var(const zend_op_array *op_array, const zend_ssa *ssa, int ssa_var_num, uint8_t var_type, uint32_t var_num, uint32_t dump_flags);
ZEND_API void zend_dump_var(const zend_op_array *op_array, uint8_t var_type, uint32_t var_num);
ZEND_API void zend_dump_ssa_var(const zend_op_array *op_array, const zend_ssa *ssa, int ssa_var_num, uint8_t var_type, int var_num, uint32_t dump_flags);
ZEND_API void zend_dump_var(const zend_op_array *op_array, uint8_t var_type, int var_num);
void zend_dump_op_array_name(const zend_op_array *op_array);
void zend_dump_const(const zval *zv);
void zend_dump_ht(HashTable *ht);

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)
{
ZEND_ASSERT(!call_info->is_frameless);
if (!call_info->send_unpack
&& (call_info->num_args == 2 || call_info->num_args == 3)
&& ssa
&& !(ssa->cfg.flags & ZEND_SSA_TSSA)) {
zend_op_array *op_array = call_info->caller_op_array;
uint32_t t1 = _ssa_op1_info(op_array, ssa, call_info->arg_info[0].opline,
ssa->ops ? &ssa->ops[call_info->arg_info[0].opline - op_array->opcodes] : NULL);
&ssa->ops[call_info->arg_info[0].opline - op_array->opcodes]);
uint32_t t2 = _ssa_op1_info(op_array, ssa, call_info->arg_info[1].opline,
ssa->ops ? &ssa->ops[call_info->arg_info[1].opline - op_array->opcodes] : NULL);
&ssa->ops[call_info->arg_info[1].opline - op_array->opcodes]);
uint32_t t3 = 0;
uint32_t tmp = MAY_BE_RC1 | MAY_BE_ARRAY;
if (call_info->num_args == 3) {
t3 = _ssa_op1_info(op_array, ssa, call_info->arg_info[2].opline,
ssa->ops ? &ssa->ops[call_info->arg_info[2].opline - op_array->opcodes] : NULL);
&ssa->ops[call_info->arg_info[2].opline - op_array->opcodes]);
}
if ((t1 & MAY_BE_STRING) && (t2 & MAY_BE_STRING)) {
tmp |= MAY_BE_ARRAY_OF_LONG | MAY_BE_ARRAY_OF_DOUBLE | MAY_BE_ARRAY_OF_STRING;

View file

@ -1,7 +1,6 @@
/* This is a generated file, edit the .stub.php files instead. */
static const func_info_t func_infos[] = {
F1("clone", MAY_BE_OBJECT),
F1("zend_version", MAY_BE_STRING),
FN("func_get_args", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_ANY),
F1("get_class_vars", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF),
@ -25,13 +24,9 @@ static const func_info_t func_infos[] = {
F1("bcmul", MAY_BE_STRING),
F1("bcdiv", MAY_BE_STRING),
F1("bcmod", MAY_BE_STRING),
F1("bcdivmod", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
F1("bcpowmod", MAY_BE_STRING),
F1("bcpow", MAY_BE_STRING),
F1("bcsqrt", MAY_BE_STRING),
F1("bcfloor", MAY_BE_STRING),
F1("bcceil", MAY_BE_STRING),
F1("bcround", MAY_BE_STRING),
FN("bzopen", MAY_BE_RESOURCE|MAY_BE_FALSE),
F1("bzerror", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING),
F1("cal_from_jd", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_NULL),
@ -47,7 +42,6 @@ static const func_info_t func_infos[] = {
F1("curl_multi_strerror", MAY_BE_STRING|MAY_BE_NULL),
F1("curl_share_init", MAY_BE_OBJECT),
F1("curl_share_strerror", MAY_BE_STRING|MAY_BE_NULL),
F1("curl_share_init_persistent", MAY_BE_OBJECT),
F1("curl_strerror", MAY_BE_STRING|MAY_BE_NULL),
F1("curl_version", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_FALSE),
F1("date", MAY_BE_STRING),
@ -80,6 +74,8 @@ static const func_info_t func_infos[] = {
F1("date_sunrise", MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_FALSE),
F1("date_sunset", MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_FALSE),
F1("date_sun_info", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_FALSE|MAY_BE_ARRAY_OF_TRUE|MAY_BE_ARRAY_OF_LONG),
FN("dba_popen", MAY_BE_RESOURCE|MAY_BE_FALSE),
FN("dba_open", MAY_BE_RESOURCE|MAY_BE_FALSE),
FN("dba_key_split", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
F1("dba_handlers", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING),
FN("dba_list", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
@ -105,6 +101,8 @@ static const func_info_t func_infos[] = {
F1("imagecreatetruecolor", MAY_BE_OBJECT|MAY_BE_FALSE),
#if defined(PHP_WIN32)
F1("imagegrabwindow", MAY_BE_OBJECT|MAY_BE_FALSE),
#endif
#if defined(PHP_WIN32)
F1("imagegrabscreen", MAY_BE_OBJECT|MAY_BE_FALSE),
#endif
F1("imagerotate", MAY_BE_OBJECT|MAY_BE_FALSE),
@ -131,11 +129,15 @@ static const func_info_t func_infos[] = {
F1("imagecreatefromgd", MAY_BE_OBJECT|MAY_BE_FALSE),
F1("imagecreatefromgd2", MAY_BE_OBJECT|MAY_BE_FALSE),
F1("imagecreatefromgd2part", MAY_BE_OBJECT|MAY_BE_FALSE),
#if defined(HAVE_GD_BMP)
F1("imagecreatefrombmp", MAY_BE_OBJECT|MAY_BE_FALSE),
#endif
F1("imagecolorsforindex", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG),
F1("imagegetclip", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_LONG),
#if defined(HAVE_GD_FREETYPE)
F1("imageftbbox", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_LONG|MAY_BE_FALSE),
#endif
#if defined(HAVE_GD_FREETYPE)
F1("imagefttext", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_LONG|MAY_BE_FALSE),
#endif
F1("imagecrop", MAY_BE_OBJECT|MAY_BE_FALSE),
@ -179,7 +181,11 @@ static const func_info_t func_infos[] = {
F1("hash_hkdf", MAY_BE_STRING),
#if defined(PHP_MHASH_BC)
F1("mhash_get_hash_name", MAY_BE_STRING|MAY_BE_FALSE),
#endif
#if defined(PHP_MHASH_BC)
F1("mhash_keygen_s2k", MAY_BE_STRING|MAY_BE_FALSE),
#endif
#if defined(PHP_MHASH_BC)
F1("mhash", MAY_BE_STRING|MAY_BE_FALSE),
#endif
F1("iconv_substr", MAY_BE_STRING|MAY_BE_FALSE),
@ -232,13 +238,29 @@ static const func_info_t func_infos[] = {
F1("mb_get_info", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_STRING|MAY_BE_LONG|MAY_BE_FALSE|MAY_BE_NULL),
#if defined(HAVE_MBREGEX)
F1("mb_regex_encoding", MAY_BE_STRING|MAY_BE_BOOL),
#endif
#if defined(HAVE_MBREGEX)
F1("mb_ereg_replace", MAY_BE_STRING|MAY_BE_FALSE|MAY_BE_NULL),
#endif
#if defined(HAVE_MBREGEX)
F1("mb_eregi_replace", MAY_BE_STRING|MAY_BE_FALSE|MAY_BE_NULL),
#endif
#if defined(HAVE_MBREGEX)
F1("mb_ereg_replace_callback", MAY_BE_STRING|MAY_BE_FALSE|MAY_BE_NULL),
#endif
#if defined(HAVE_MBREGEX)
F1("mb_split", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
#endif
#if defined(HAVE_MBREGEX)
F1("mb_ereg_search_pos", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_LONG|MAY_BE_FALSE),
#endif
#if defined(HAVE_MBREGEX)
F1("mb_ereg_search_regs", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_FALSE|MAY_BE_FALSE),
#endif
#if defined(HAVE_MBREGEX)
F1("mb_ereg_search_getregs", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_FALSE|MAY_BE_FALSE),
#endif
#if defined(HAVE_MBREGEX)
F1("mb_regex_set_options", MAY_BE_STRING),
#endif
F1("mysqli_affected_rows", MAY_BE_LONG|MAY_BE_STRING),
@ -286,6 +308,39 @@ static const func_info_t func_infos[] = {
F1("mysqli_stat", MAY_BE_STRING|MAY_BE_FALSE),
F1("mysqli_store_result", MAY_BE_OBJECT|MAY_BE_FALSE),
F1("mysqli_use_result", MAY_BE_OBJECT|MAY_BE_FALSE),
FN("oci_new_connect", MAY_BE_RESOURCE|MAY_BE_FALSE),
FN("oci_connect", MAY_BE_RESOURCE|MAY_BE_FALSE),
FN("oci_pconnect", MAY_BE_RESOURCE|MAY_BE_FALSE),
F1("oci_error", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
FN("oci_parse", MAY_BE_RESOURCE|MAY_BE_FALSE),
FN("oci_get_implicit_resultset", MAY_BE_RESOURCE|MAY_BE_FALSE),
FN("oci_password_change", MAY_BE_RESOURCE|MAY_BE_BOOL),
FN("oci_new_cursor", MAY_BE_RESOURCE|MAY_BE_FALSE),
FN("odbc_prepare", MAY_BE_RESOURCE|MAY_BE_FALSE),
FN("odbc_exec", MAY_BE_RESOURCE|MAY_BE_FALSE),
FN("odbc_connect", MAY_BE_RESOURCE|MAY_BE_FALSE),
FN("odbc_pconnect", MAY_BE_RESOURCE|MAY_BE_FALSE),
FN("odbc_tables", MAY_BE_RESOURCE|MAY_BE_FALSE),
FN("odbc_columns", MAY_BE_RESOURCE|MAY_BE_FALSE),
FN("odbc_gettypeinfo", MAY_BE_RESOURCE|MAY_BE_FALSE),
FN("odbc_primarykeys", MAY_BE_RESOURCE|MAY_BE_FALSE),
#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35)
FN("odbc_procedurecolumns", MAY_BE_RESOURCE|MAY_BE_FALSE),
#endif
#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35)
FN("odbc_procedures", MAY_BE_RESOURCE|MAY_BE_FALSE),
#endif
#if !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) && !defined(HAVE_SOLID_35)
FN("odbc_foreignkeys", MAY_BE_RESOURCE|MAY_BE_FALSE),
#endif
FN("odbc_specialcolumns", MAY_BE_RESOURCE|MAY_BE_FALSE),
FN("odbc_statistics", MAY_BE_RESOURCE|MAY_BE_FALSE),
#if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) &&!defined(HAVE_SOLID_35)
FN("odbc_tableprivileges", MAY_BE_RESOURCE|MAY_BE_FALSE),
#endif
#if !defined(HAVE_DBMAKER) && !defined(HAVE_SOLID) && !defined(HAVE_SOLID_30) &&!defined(HAVE_SOLID_35)
FN("odbc_columnprivileges", MAY_BE_RESOURCE|MAY_BE_FALSE),
#endif
F1("opcache_get_status", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_FALSE),
F1("opcache_get_configuration", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_ANY|MAY_BE_FALSE),
F1("openssl_x509_parse", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_FALSE),
@ -310,7 +365,6 @@ static const func_info_t func_infos[] = {
F1("pg_tty", MAY_BE_STRING),
F1("pg_host", MAY_BE_STRING),
F1("pg_version", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_NULL),
F1("pg_jit", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_NULL),
F1("pg_parameter_status", MAY_BE_STRING|MAY_BE_FALSE),
F1("pg_query", MAY_BE_OBJECT|MAY_BE_FALSE),
F1("pg_query_params", MAY_BE_OBJECT|MAY_BE_FALSE),
@ -360,6 +414,7 @@ static const func_info_t func_infos[] = {
#if defined(HAVE_GETRLIMIT)
F1("posix_getrlimit", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
#endif
F1("pspell_suggest", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
F1("random_bytes", MAY_BE_STRING),
#if defined(HAVE_HISTORY_LIST)
F1("readline_list_history", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
@ -379,6 +434,8 @@ static const func_info_t func_infos[] = {
FN("sodium_crypto_kx_server_session_keys", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
#if defined(crypto_secretstream_xchacha20poly1305_ABYTES)
FN("sodium_crypto_secretstream_xchacha20poly1305_init_push", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
#endif
#if defined(crypto_secretstream_xchacha20poly1305_ABYTES)
FN("sodium_crypto_secretstream_xchacha20poly1305_pull", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
#endif
F1("class_implements", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
@ -413,7 +470,7 @@ static const func_info_t func_infos[] = {
FN("array_rand", MAY_BE_LONG|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING),
F1("base64_encode", MAY_BE_STRING),
F1("base64_decode", MAY_BE_STRING|MAY_BE_FALSE),
F1("long2ip", MAY_BE_STRING),
F1("long2ip", MAY_BE_STRING|MAY_BE_FALSE),
F1("getenv", MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
F1("getopt", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_FALSE|MAY_BE_FALSE),
#if defined(HAVE_NANOSLEEP)
@ -421,13 +478,14 @@ static const func_info_t func_infos[] = {
#endif
F1("get_current_user", MAY_BE_STRING),
FN("get_cfg_var", MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_FALSE),
F1("error_get_last", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_NULL),
F1("error_get_last", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_NULL),
F1("highlight_file", MAY_BE_STRING|MAY_BE_BOOL),
F1("php_strip_whitespace", MAY_BE_STRING),
F1("highlight_string", MAY_BE_STRING|MAY_BE_TRUE),
F1("highlight_string", MAY_BE_STRING|MAY_BE_BOOL),
F1("ini_get_all", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_NULL|MAY_BE_FALSE),
F1("set_include_path", MAY_BE_STRING|MAY_BE_FALSE),
F1("print_r", MAY_BE_STRING|MAY_BE_TRUE),
F1("get_include_path", MAY_BE_STRING|MAY_BE_FALSE),
F1("print_r", MAY_BE_STRING|MAY_BE_BOOL),
#if defined(HAVE_GETSERVBYPORT)
F1("getservbyport", MAY_BE_STRING|MAY_BE_FALSE),
#endif
@ -460,8 +518,12 @@ static const func_info_t func_infos[] = {
F1("md5_file", MAY_BE_STRING|MAY_BE_FALSE),
F1("sha1", MAY_BE_STRING),
F1("sha1_file", MAY_BE_STRING|MAY_BE_FALSE),
#if defined(HAVE_INET_NTOP)
F1("inet_ntop", MAY_BE_STRING|MAY_BE_FALSE),
#endif
#if defined(HAVE_INET_PTON)
F1("inet_pton", MAY_BE_STRING|MAY_BE_FALSE),
#endif
F1("metaphone", MAY_BE_STRING),
F1("headers_list", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
F1("htmlspecialchars", MAY_BE_STRING),
@ -510,7 +572,9 @@ static const func_info_t func_infos[] = {
F1("getcwd", MAY_BE_STRING|MAY_BE_FALSE),
F1("readdir", MAY_BE_STRING|MAY_BE_FALSE),
F1("scandir", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
#if defined(HAVE_GLOB)
F1("glob", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
#endif
F1("exec", MAY_BE_STRING|MAY_BE_FALSE),
F1("system", MAY_BE_STRING|MAY_BE_FALSE),
F1("escapeshellcmd", MAY_BE_STRING),
@ -539,7 +603,6 @@ static const func_info_t func_infos[] = {
F1("fsockopen", MAY_BE_RESOURCE|MAY_BE_FALSE),
FN("pfsockopen", MAY_BE_RESOURCE|MAY_BE_FALSE),
F1("http_build_query", MAY_BE_STRING),
F1("request_parse_body", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_ARRAY),
F1("image_type_to_mime_type", MAY_BE_STRING),
F1("image_type_to_extension", MAY_BE_STRING|MAY_BE_FALSE),
F1("getimagesize", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_FALSE),
@ -561,6 +624,8 @@ static const func_info_t func_infos[] = {
F1("number_format", MAY_BE_STRING),
#if defined(HAVE_GETTIMEOFDAY)
F1("microtime", MAY_BE_STRING|MAY_BE_DOUBLE),
#endif
#if defined(HAVE_GETTIMEOFDAY)
F1("gettimeofday", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_DOUBLE),
#endif
#if defined(HAVE_GETRUSAGE)
@ -572,6 +637,8 @@ static const func_info_t func_infos[] = {
F1("password_hash", MAY_BE_STRING),
#if defined(PHP_CAN_SUPPORT_PROC_OPEN)
F1("proc_open", MAY_BE_RESOURCE|MAY_BE_FALSE),
#endif
#if defined(PHP_CAN_SUPPORT_PROC_OPEN)
F1("proc_get_status", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_FALSE|MAY_BE_ARRAY_OF_TRUE|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING),
#endif
F1("quoted_printable_decode", MAY_BE_STRING),

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" */
static zend_ulong minOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
zend_ulong minOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
{
zend_ulong m, temp;
@ -567,7 +567,7 @@ static zend_ulong minOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
return a | c;
}
static zend_ulong maxOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
zend_ulong maxOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
{
zend_ulong m, temp;
@ -590,7 +590,7 @@ static zend_ulong maxOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
return b | d;
}
static zend_ulong minAND(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
zend_ulong minAND(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
{
zend_ulong m, temp;
@ -613,7 +613,7 @@ static zend_ulong minAND(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
return a & c;
}
static zend_ulong maxAND(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
zend_ulong maxAND(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
{
zend_ulong m, temp;
@ -637,6 +637,16 @@ static zend_ulong maxAND(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
return b & d;
}
zend_ulong minXOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
{
return minAND(a, b, ~d, ~c) | minAND(~b, ~a, c, d);
}
zend_ulong maxXOR(zend_ulong a, zend_ulong b, zend_ulong c, zend_ulong d)
{
return maxOR(0, maxAND(a, b, ~d, ~c), 0, maxAND(~b, ~a, c, d));
}
/* Based on "Hacker's Delight" */
/*
@ -1968,10 +1978,6 @@ static uint32_t get_ssa_alias_types(zend_ssa_alias_kind alias) {
/* TODO: support for array keys and ($str . "")*/ \
__type |= MAY_BE_RCN; \
} \
if ((__type & MAY_BE_RC1) && (__type & MAY_BE_OBJECT)) {\
/* TODO: object may be captured by magic handlers */\
__type |= MAY_BE_RCN; \
} \
if (__ssa_var->alias) { \
__type |= get_ssa_alias_types(__ssa_var->alias); \
} \
@ -1997,15 +2003,10 @@ static uint32_t get_ssa_alias_types(zend_ssa_alias_kind alias) {
#define UPDATE_SSA_OBJ_TYPE(_ce, _is_instanceof, var) \
do { \
if (var >= 0) { \
zend_class_entry *__ce = (_ce); \
bool __is_instanceof = (_is_instanceof); \
if (__ce && (__ce->ce_flags & ZEND_ACC_FINAL)) { \
__is_instanceof = false; \
} \
if (ssa_var_info[var].ce != __ce || \
ssa_var_info[var].is_instanceof != __is_instanceof) { \
ssa_var_info[var].ce = __ce; \
ssa_var_info[var].is_instanceof = __is_instanceof; \
if (ssa_var_info[var].ce != (_ce) || \
ssa_var_info[var].is_instanceof != (_is_instanceof)) { \
ssa_var_info[var].ce = (_ce); \
ssa_var_info[var].is_instanceof = (_is_instanceof); \
if (update_worklist) { \
add_usages(op_array, ssa, worklist, var); \
} \
@ -2409,7 +2410,7 @@ static const zend_property_info *lookup_prop_info(const zend_class_entry *ce, ze
/* If the class is linked, reuse the precise runtime logic. */
if ((ce->ce_flags & ZEND_ACC_LINKED)
&& (!scope || (scope->ce_flags & ZEND_ACC_LINKED))) {
const zend_class_entry *prev_scope = EG(fake_scope);
zend_class_entry *prev_scope = EG(fake_scope);
EG(fake_scope) = scope;
prop_info = zend_get_property_info(ce, name, 1);
EG(fake_scope) = prev_scope;
@ -3023,14 +3024,7 @@ static zend_always_inline zend_result _zend_update_type_info(
break;
case ZEND_ASSIGN_OBJ:
if (opline->op1_type == IS_CV) {
zend_class_entry *ce = ssa_var_info[ssa_op->op1_use].ce;
bool add_rc = (t1 & (MAY_BE_OBJECT|MAY_BE_REF)) && (!ce
|| ce->__set
/* Non-default write_property may be set within create_object. */
|| ce->create_object
|| ce->default_object_handlers->write_property != zend_std_write_property
|| ssa_var_info[ssa_op->op1_use].is_instanceof);
tmp = (t1 & (MAY_BE_REF|MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN))|(add_rc ? (MAY_BE_RC1|MAY_BE_RCN) : 0);
tmp = (t1 & (MAY_BE_REF|MAY_BE_OBJECT))|MAY_BE_RC1|MAY_BE_RCN;
UPDATE_SSA_TYPE(tmp, ssa_op->op1_def);
COPY_SSA_OBJ_TYPE(ssa_op->op1_use, ssa_op->op1_def);
}
@ -3163,7 +3157,7 @@ static zend_always_inline zend_result _zend_update_type_info(
}
break;
case ZEND_ASSIGN_OBJ_REF:
if (opline->op1_type == IS_CV && ssa_op->op1_def >= 0) {
if (opline->op1_type == IS_CV) {
tmp = t1;
if (tmp & MAY_BE_OBJECT) {
tmp |= MAY_BE_RC1 | MAY_BE_RCN;
@ -3354,12 +3348,6 @@ static zend_always_inline zend_result _zend_update_type_info(
}
break;
case ZEND_FETCH_CLASS_STATIC:
if (op_array->scope && (op_array->scope->ce_flags & ZEND_ACC_FINAL)) {
UPDATE_SSA_OBJ_TYPE(op_array->scope, 0, ssa_op->result_def);
} else {
UPDATE_SSA_OBJ_TYPE(NULL, 0, ssa_op->result_def);
}
break;
default:
UPDATE_SSA_OBJ_TYPE(NULL, 0, ssa_op->result_def);
break;
@ -3383,19 +3371,9 @@ static zend_always_inline zend_result _zend_update_type_info(
UPDATE_SSA_OBJ_TYPE(ce, 0, ssa_op->result_def);
} else if ((t1 & MAY_BE_CLASS) && ssa_op->op1_use >= 0 && ssa_var_info[ssa_op->op1_use].ce) {
UPDATE_SSA_OBJ_TYPE(ssa_var_info[ssa_op->op1_use].ce, ssa_var_info[ssa_op->op1_use].is_instanceof, ssa_op->result_def);
if (!ssa_var_info[ssa_op->result_def].is_instanceof) {
ce = ssa_var_info[ssa_op->op1_use].ce;
}
} else {
UPDATE_SSA_OBJ_TYPE(NULL, 0, ssa_op->result_def);
}
/* New objects without constructors cannot escape. */
if (ce
&& !ce->constructor
&& !ce->create_object
&& ce->default_object_handlers->get_constructor == zend_std_get_constructor) {
tmp &= ~MAY_BE_RCN;
}
UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
break;
case ZEND_CLONE:
@ -3843,38 +3821,6 @@ static zend_always_inline zend_result _zend_update_type_info(
UPDATE_SSA_OBJ_TYPE(ce, 1, ssa_op->result_def);
}
break;
case ZEND_FRAMELESS_ICALL_1:
case ZEND_FRAMELESS_ICALL_2:
case ZEND_FRAMELESS_ICALL_3:
if (ssa_op->op1_def >= 0) {
ZEND_ASSERT(ssa_op->op1_use >= 0);
tmp = ssa->var_info[ssa_op->op1_use].type;
if (tmp & MAY_BE_RC1) {
tmp |= MAY_BE_RCN;
}
UPDATE_SSA_TYPE(tmp, ssa_op->op1_def);
}
if (ssa_op->op2_def >= 0) {
ZEND_ASSERT(ssa_op->op2_use >= 0);
tmp = ssa->var_info[ssa_op->op2_use].type;
if (tmp & MAY_BE_RC1) {
tmp |= MAY_BE_RCN;
}
UPDATE_SSA_TYPE(tmp, ssa_op->op2_def);
}
if (opline->opcode == ZEND_FRAMELESS_ICALL_3) {
zend_ssa_op *next_ssa_op = ssa_op + 1;
if (next_ssa_op->op1_def >= 0) {
ZEND_ASSERT(next_ssa_op->op1_use >= 0);
tmp = ssa->var_info[next_ssa_op->op1_use].type;
if (tmp & MAY_BE_RC1) {
tmp |= MAY_BE_RCN;
}
UPDATE_SSA_TYPE(tmp, next_ssa_op->op1_def);
}
}
ZEND_FALLTHROUGH;
case ZEND_FRAMELESS_ICALL_0:
case ZEND_DO_FCALL:
case ZEND_DO_ICALL:
case ZEND_DO_UCALL:
@ -3905,21 +3851,9 @@ static zend_always_inline zend_result _zend_update_type_info(
UPDATE_SSA_OBJ_TYPE(zend_ce_closure, /* is_instanceof */ false, ssa_op->result_def);
break;
case ZEND_FETCH_CONSTANT:
case ZEND_FETCH_CLASS_CONSTANT:
UPDATE_SSA_TYPE(MAY_BE_RC1|MAY_BE_RCN|MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY, ssa_op->result_def);
break;
case ZEND_FETCH_CLASS_CONSTANT: {
bool is_prototype;
const zend_class_constant *cc = zend_fetch_class_const_info(script, op_array, opline, &is_prototype);
if (!cc || !ZEND_TYPE_IS_SET(cc->type)) {
UPDATE_SSA_TYPE(MAY_BE_RC1|MAY_BE_RCN|MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY, ssa_op->result_def);
break;
}
UPDATE_SSA_TYPE(zend_convert_type(script, cc->type, &ce), ssa_op->result_def);
if (ce) {
UPDATE_SSA_OBJ_TYPE(ce, /* is_instanceof */ true, ssa_op->result_def);
}
break;
}
case ZEND_STRLEN:
case ZEND_COUNT:
case ZEND_FUNC_NUM_ARGS:
@ -4001,73 +3935,12 @@ static zend_always_inline zend_result _zend_update_type_info(
/* Forbidden opcodes */
ZEND_UNREACHABLE();
break;
case ZEND_FETCH_CLASS_NAME:
UPDATE_SSA_TYPE(MAY_BE_STRING|MAY_BE_RCN, ssa_op->result_def);
break;
case ZEND_ISSET_ISEMPTY_THIS:
UPDATE_SSA_TYPE(MAY_BE_BOOL, ssa_op->result_def);
break;
case ZEND_DECLARE_LAMBDA_FUNCTION:
UPDATE_SSA_TYPE(MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN, ssa_op->result_def);
UPDATE_SSA_OBJ_TYPE(zend_ce_closure, /* is_instanceof */ false, ssa_op->result_def);
break;
case ZEND_PRE_DEC_STATIC_PROP:
case ZEND_PRE_INC_STATIC_PROP:
case ZEND_POST_DEC_STATIC_PROP:
case ZEND_POST_INC_STATIC_PROP: {
if (ssa_op->result_def >= 0) {
const zend_property_info *prop_info = zend_fetch_static_prop_info(script, op_array, ssa, opline);
zend_class_entry *prop_ce;
tmp = zend_fetch_prop_type(script, prop_info, &prop_ce);
/* Internal objects may result in essentially anything. */
if (tmp & MAY_BE_OBJECT) {
goto unknown_opcode;
}
tmp &= MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING|MAY_BE_BOOL|MAY_BE_NULL;
if (tmp & MAY_BE_STRING) {
tmp |= MAY_BE_RC1 | MAY_BE_RCN;
}
UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
}
break;
}
case ZEND_SPACESHIP:
UPDATE_SSA_TYPE(MAY_BE_LONG, ssa_op->result_def);
break;
case ZEND_FETCH_GLOBALS:
UPDATE_SSA_TYPE(MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF|MAY_BE_RC1|MAY_BE_RCN, ssa_op->result_def);
break;
default:
#ifdef ZEND_DEBUG_TYPE_INFERENCE
if (ssa_op->result_def >= 0) {
switch (opline->opcode) {
case ZEND_FETCH_R:
case ZEND_FETCH_W:
case ZEND_FETCH_RW:
case ZEND_FETCH_IS:
case ZEND_FETCH_UNSET:
case ZEND_YIELD_FROM:
/* Currently unimplemented due to some assumptions in JIT. See:
* https://github.com/php/php-src/pull/13304#issuecomment-1926668141 */
case ZEND_SEPARATE:
break;
default:
fprintf(stderr, "Missing result type inference for opcode %s, line %d\n", zend_get_opcode_name(opline->opcode), opline->lineno);
break;
}
}
if (ssa_op->op1_def >= 0) {
fprintf(stderr, "Missing op1 type inference for opcode %s, line %d\n", zend_get_opcode_name(opline->opcode), opline->lineno);
}
if (ssa_op->op2_def >= 0) {
fprintf(stderr, "Missing op2 type inference for opcode %s, line %d\n", zend_get_opcode_name(opline->opcode), opline->lineno);
}
#endif
unknown_opcode:
if (ssa_op->op1_def >= 0) {
tmp = MAY_BE_ANY | MAY_BE_REF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
UPDATE_SSA_TYPE(tmp, ssa_op->op1_def);
}
unknown_opcode:
if (ssa_op->result_def >= 0) {
tmp = MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
if (opline->result_type == IS_TMP_VAR) {
@ -5005,6 +4878,8 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op
switch (opline->opcode) {
case ZEND_NOP:
case ZEND_IS_IDENTICAL:
case ZEND_IS_NOT_IDENTICAL:
case ZEND_QM_ASSIGN:
case ZEND_JMP:
case ZEND_CHECK_VAR:
@ -5026,14 +4901,9 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op
case ZEND_FUNC_NUM_ARGS:
case ZEND_FUNC_GET_ARGS:
case ZEND_COPY_TMP:
case ZEND_JMP_NULL:
case ZEND_JMP_FRAMELESS:
return 0;
case ZEND_IS_IDENTICAL:
case ZEND_IS_NOT_IDENTICAL:
case ZEND_CASE_STRICT:
/* Array to array comparison may lead to recursion. */
return (t1 & t2) & MAY_BE_ARRAY_OF_ARRAY;
case ZEND_JMP_NULL:
return 0;
case ZEND_SEND_VAR:
case ZEND_SEND_VAL:
case ZEND_SEND_REF:
@ -5184,7 +5054,7 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op
return 0;
case ZEND_ASSIGN_DIM:
if ((opline+1)->op1_type == IS_CV) {
if (OP1_DATA_INFO() & MAY_BE_UNDEF) {
if (_ssa_op1_info(op_array, ssa, opline+1, ssa_op+1) & MAY_BE_UNDEF) {
return 1;
}
}
@ -5198,7 +5068,7 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op
return 1;
}
if ((opline+1)->op1_type == IS_CV) {
if (OP1_DATA_INFO() & MAY_BE_UNDEF) {
if (_ssa_op1_info(op_array, ssa, opline+1, ssa_op+1) & MAY_BE_UNDEF) {
return 1;
}
}

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 OP2_INFO() (_ssa_op2_info(op_array, ssa, opline, ssa_op))
#define OP1_DATA_INFO() (_ssa_op1_info(op_array, ssa, (opline+1), ssa_op ? (ssa_op+1) : NULL))
#define OP2_DATA_INFO() (_ssa_op2_info(op_array, ssa, (opline+1), ssa_op ? (ssa_op+1) : NULL))
#define OP1_DATA_INFO() (_ssa_op1_info(op_array, ssa, (opline+1), (ssa_op+1)))
#define OP2_DATA_INFO() (_ssa_op2_info(op_array, ssa, (opline+1), (ssa_op+1)))
#define RES_USE_INFO() (_ssa_result_info(op_array, ssa, opline, ssa_op))
#define OP1_DEF_INFO() (_ssa_op1_def_info(op_array, ssa, opline, ssa_op))
#define OP2_DEF_INFO() (_ssa_op2_def_info(op_array, ssa, opline, ssa_op))
#define OP1_DATA_DEF_INFO() (_ssa_op1_def_info(op_array, ssa, (opline+1), ssa_op ? (ssa_op+1) : NULL))
#define OP2_DATA_DEF_INFO() (_ssa_op2_def_info(op_array, ssa, (opline+1), ssa_op ? (ssa_op+1) : NULL))
#define OP1_DATA_DEF_INFO() (_ssa_op1_def_info(op_array, ssa, (opline+1), (ssa_op+1)))
#define OP2_DATA_DEF_INFO() (_ssa_op2_def_info(op_array, ssa, (opline+1), (ssa_op+1)))
#define RES_INFO() (_ssa_result_def_info(op_array, ssa, opline, ssa_op))
static zend_always_inline bool zend_add_will_overflow(zend_long a, zend_long b) {

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) /* {{{ */
{
if (zend_try_ct_eval_cast(result, type, op1)) {
return SUCCESS;
switch (type) {
case IS_NULL:
ZVAL_NULL(result);
return SUCCESS;
case _IS_BOOL:
ZVAL_BOOL(result, zval_is_true(op1));
return SUCCESS;
case IS_LONG:
ZVAL_LONG(result, zval_get_long(op1));
return SUCCESS;
case IS_DOUBLE:
ZVAL_DOUBLE(result, zval_get_double(op1));
return SUCCESS;
case IS_STRING:
/* Conversion from double to string takes into account run-time
'precision' setting and cannot be evaluated at compile-time */
if (Z_TYPE_P(op1) != IS_ARRAY && Z_TYPE_P(op1) != IS_DOUBLE) {
ZVAL_STR(result, zval_get_string(op1));
return SUCCESS;
}
break;
case IS_ARRAY:
ZVAL_COPY(result, op1);
convert_to_array(result);
return SUCCESS;
}
return FAILURE;
}
@ -699,7 +722,6 @@ void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, z
case ZEND_ASSERT_CHECK:
case ZEND_JMP_NULL:
case ZEND_BIND_INIT_STATIC_OR_JMP:
case ZEND_JMP_FRAMELESS:
ZEND_SET_OP_JMP_ADDR(new_opline, new_opline->op2, ZEND_OP2_JMP_ADDR(opline));
break;
case ZEND_FE_FETCH_R:
@ -744,7 +766,6 @@ void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_
case ZEND_ASSERT_CHECK:
case ZEND_JMP_NULL:
case ZEND_BIND_INIT_STATIC_OR_JMP:
case ZEND_JMP_FRAMELESS:
ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP2_JMP_ADDR(opline) - shiftlist[ZEND_OP2_JMP_ADDR(opline) - op_array->opcodes]);
break;
case ZEND_CATCH:
@ -771,42 +792,6 @@ void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_
}
}
static bool zend_optimizer_ignore_class(zval *ce_zv, zend_string *filename)
{
zend_class_entry *ce = Z_PTR_P(ce_zv);
if (ce->ce_flags & ZEND_ACC_PRELOADED) {
Bucket *ce_bucket = (Bucket*)((uintptr_t)ce_zv - XtOffsetOf(Bucket, val));
size_t offset = ce_bucket - EG(class_table)->arData;
if (offset < EG(persistent_classes_count)) {
return false;
}
}
return ce->type == ZEND_USER_CLASS
&& (!ce->info.user.filename || ce->info.user.filename != filename);
}
static bool zend_optimizer_ignore_function(zval *fbc_zv, zend_string *filename)
{
zend_function *fbc = Z_PTR_P(fbc_zv);
if (fbc->type == ZEND_INTERNAL_FUNCTION) {
return false;
} else if (fbc->type == ZEND_USER_FUNCTION) {
if (fbc->op_array.fn_flags & ZEND_ACC_PRELOADED) {
Bucket *fbc_bucket = (Bucket*)((uintptr_t)fbc_zv - XtOffsetOf(Bucket, val));
size_t offset = fbc_bucket - EG(function_table)->arData;
if (offset < EG(persistent_functions_count)) {
return false;
}
}
return !fbc->op_array.filename || fbc->op_array.filename != filename;
} else {
ZEND_ASSERT(fbc->type == ZEND_EVAL_CODE);
return true;
}
}
zend_class_entry *zend_optimizer_get_class_entry(
const zend_script *script, const zend_op_array *op_array, zend_string *lcname) {
zend_class_entry *ce = script ? zend_hash_find_ptr(&script->class_table, lcname) : NULL;
@ -814,9 +799,11 @@ zend_class_entry *zend_optimizer_get_class_entry(
return ce;
}
zval *ce_zv = zend_hash_find(CG(class_table), lcname);
if (ce_zv && !zend_optimizer_ignore_class(ce_zv, op_array ? op_array->filename : NULL)) {
return Z_PTR_P(ce_zv);
ce = zend_hash_find_ptr(CG(class_table), lcname);
if (ce
&& (ce->type == ZEND_INTERNAL_CLASS
|| (op_array && ce->info.user.filename == op_array->filename))) {
return ce;
}
if (op_array && op_array->scope && zend_string_equals_ci(op_array->scope->name, lcname)) {
@ -835,66 +822,12 @@ zend_class_entry *zend_optimizer_get_class_entry_from_op1(
}
} else if (opline->op1_type == IS_UNUSED && op_array->scope
&& !(op_array->scope->ce_flags & ZEND_ACC_TRAIT)
&& ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF
|| ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_STATIC
&& (op_array->scope->ce_flags & ZEND_ACC_FINAL)))) {
&& (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) {
return op_array->scope;
}
return NULL;
}
const zend_class_constant *zend_fetch_class_const_info(
const zend_script *script, const zend_op_array *op_array, const zend_op *opline, bool *is_prototype) {
const zend_class_entry *ce = NULL;
bool is_static_reference = false;
if (!opline || !op_array || opline->op2_type != IS_CONST || Z_TYPE_P(CRT_CONSTANT(opline->op2)) != IS_STRING) {
return NULL;
}
if (opline->op1_type == IS_CONST) {
zval *op1 = CRT_CONSTANT(opline->op1);
if (Z_TYPE_P(op1) == IS_STRING) {
if (script) {
ce = zend_optimizer_get_class_entry(script, op_array, Z_STR_P(op1 + 1));
} else {
zval *ce_zv = zend_hash_find(EG(class_table), Z_STR_P(op1 + 1));
if (ce_zv && !zend_optimizer_ignore_class(ce_zv, op_array->filename)) {
ce = Z_PTR_P(ce_zv);
}
}
}
} else if (opline->op1_type == IS_UNUSED
&& op_array->scope && !(op_array->scope->ce_flags & ZEND_ACC_TRAIT)
&& !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) {
int fetch_type = opline->op1.num & ZEND_FETCH_CLASS_MASK;
if (fetch_type == ZEND_FETCH_CLASS_SELF) {
ce = op_array->scope;
} else if (fetch_type == ZEND_FETCH_CLASS_STATIC) {
ce = op_array->scope;
is_static_reference = true;
} else if (fetch_type == ZEND_FETCH_CLASS_PARENT) {
if (op_array->scope->ce_flags & ZEND_ACC_LINKED) {
ce = op_array->scope->parent;
}
}
}
if (!ce || (ce->ce_flags & ZEND_ACC_TRAIT)) {
return NULL;
}
zend_class_constant *const_info = zend_hash_find_ptr(&ce->constants_table, Z_STR_P(CRT_CONSTANT(opline->op2)));
if (!const_info) {
return NULL;
}
if ((ZEND_CLASS_CONST_FLAGS(const_info) & ZEND_ACC_DEPRECATED)
|| ((ZEND_CLASS_CONST_FLAGS(const_info) & ZEND_ACC_PPP_MASK) != ZEND_ACC_PUBLIC && const_info->ce != op_array->scope)) {
return NULL;
}
*is_prototype = is_static_reference
&& !(const_info->ce->ce_flags & ZEND_ACC_FINAL) && !(ZEND_CLASS_CONST_FLAGS(const_info) & ZEND_ACC_FINAL);
return const_info;
}
zend_function *zend_optimizer_get_called_func(
zend_script *script, zend_op_array *op_array, zend_op *opline, bool *is_prototype)
{
@ -904,12 +837,15 @@ zend_function *zend_optimizer_get_called_func(
{
zend_string *function_name = Z_STR_P(CRT_CONSTANT(opline->op2));
zend_function *func;
zval *func_zv;
if (script && (func = zend_hash_find_ptr(&script->function_table, function_name)) != NULL) {
return func;
} else if ((func_zv = zend_hash_find(EG(function_table), function_name)) != NULL) {
if (!zend_optimizer_ignore_function(func_zv, op_array->filename)) {
return Z_PTR_P(func_zv);
} else if ((func = zend_hash_find_ptr(EG(function_table), function_name)) != NULL) {
if (func->type == ZEND_INTERNAL_FUNCTION) {
return func;
} else if (func->type == ZEND_USER_FUNCTION &&
func->op_array.filename &&
func->op_array.filename == op_array->filename) {
return func;
}
}
break;
@ -919,12 +855,15 @@ zend_function *zend_optimizer_get_called_func(
if (opline->op2_type == IS_CONST && Z_TYPE_P(CRT_CONSTANT(opline->op2)) == IS_STRING) {
zval *function_name = CRT_CONSTANT(opline->op2) + 1;
zend_function *func;
zval *func_zv;
if (script && (func = zend_hash_find_ptr(&script->function_table, Z_STR_P(function_name)))) {
return func;
} else if ((func_zv = zend_hash_find(EG(function_table), Z_STR_P(function_name))) != NULL) {
if (!zend_optimizer_ignore_function(func_zv, op_array->filename)) {
return Z_PTR_P(func_zv);
} else if ((func = zend_hash_find_ptr(EG(function_table), Z_STR_P(function_name))) != NULL) {
if (func->type == ZEND_INTERNAL_FUNCTION) {
return func;
} else if (func->type == ZEND_USER_FUNCTION &&
func->op_array.filename &&
func->op_array.filename == op_array->filename) {
return func;
}
}
}
@ -974,28 +913,6 @@ zend_function *zend_optimizer_get_called_func(
}
}
break;
case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL: {
zend_class_entry *scope = op_array->scope;
ZEND_ASSERT(scope != NULL);
if ((scope->ce_flags & ZEND_ACC_LINKED) && scope->parent) {
zend_class_entry *parent_scope = scope->parent;
zend_string *prop_name = Z_STR_P(CRT_CONSTANT(opline->op1));
zend_property_hook_kind hook_kind = opline->op2.num;
zend_property_info *prop_info = zend_get_property_info(parent_scope, prop_name, /* silent */ true);
if (prop_info
&& prop_info != ZEND_WRONG_PROPERTY_INFO
&& !(prop_info->flags & ZEND_ACC_PRIVATE)
&& prop_info->hooks) {
zend_function *fbc = prop_info->hooks[hook_kind];
if (fbc) {
*is_prototype = false;
return fbc;
}
}
}
break;
}
case ZEND_NEW:
{
zend_class_entry *ce = zend_optimizer_get_class_entry_from_op1(
@ -1242,7 +1159,6 @@ static void zend_redo_pass_two(zend_op_array *op_array)
case ZEND_ASSERT_CHECK:
case ZEND_JMP_NULL:
case ZEND_BIND_INIT_STATIC_OR_JMP:
case ZEND_JMP_FRAMELESS:
opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes];
break;
case ZEND_CATCH:
@ -1364,7 +1280,6 @@ static void zend_redo_pass_two_ex(zend_op_array *op_array, zend_ssa *ssa)
case ZEND_ASSERT_CHECK:
case ZEND_JMP_NULL:
case ZEND_BIND_INIT_STATIC_OR_JMP:
case ZEND_JMP_FRAMELESS:
opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes];
break;
case ZEND_CATCH:
@ -1414,26 +1329,6 @@ static void zend_redo_pass_two_ex(zend_op_array *op_array, zend_ssa *ssa)
}
break;
}
#ifdef ZEND_VERIFY_TYPE_INFERENCE
if (ssa_op->op1_use >= 0) {
opline->op1_use_type = ssa->var_info[ssa_op->op1_use].type;
}
if (ssa_op->op2_use >= 0) {
opline->op2_use_type = ssa->var_info[ssa_op->op2_use].type;
}
if (ssa_op->result_use >= 0) {
opline->result_use_type = ssa->var_info[ssa_op->result_use].type;
}
if (ssa_op->op1_def >= 0) {
opline->op1_def_type = ssa->var_info[ssa_op->op1_def].type;
}
if (ssa_op->op2_def >= 0) {
opline->op2_def_type = ssa->var_info[ssa_op->op2_def].type;
}
if (ssa_op->result_def >= 0) {
opline->result_def_type = ssa->var_info[ssa_op->result_def].type;
}
#endif
zend_vm_set_opcode_handler_ex(opline, op1_info, op2_info, res_info);
opline++;
}
@ -1549,19 +1444,6 @@ void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void
zend_foreach_op_array_helper(op_array, func, context);
}
} ZEND_HASH_FOREACH_END();
zend_property_info *property;
ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, property) {
zend_function **hooks = property->hooks;
if (property->ce == ce && property->hooks) {
for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) {
zend_function *hook = hooks[i];
if (hook && hook->common.scope == ce && !(hooks[i]->op_array.fn_flags & ZEND_ACC_TRAIT_CLONE)) {
zend_foreach_op_array_helper(&hooks[i]->op_array, func, context);
}
}
}
} ZEND_HASH_FOREACH_END();
} ZEND_HASH_FOREACH_END();
}

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_result zend_optimizer_startup(void);
zend_result zend_optimizer_shutdown(void);
typedef void (*zend_op_array_func_t)(zend_op_array *, void *context);
void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void *context);
END_EXTERN_C()
#endif

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);
zend_class_entry *zend_optimizer_get_class_entry_from_op1(
const zend_script *script, const zend_op_array *op_array, const zend_op *opline);
const zend_class_constant *zend_fetch_class_const_info(
const zend_script *script, const zend_op_array *op_array, const zend_op *opline, bool *is_prototype);
void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx);
void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx);
@ -128,4 +126,7 @@ int sccp_optimize_op_array(zend_optimizer_ctx *ctx, zend_op_array *op_array, zen
int dce_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *optimizer_ctx, zend_ssa *ssa, bool reorder_dtor_effects);
zend_result zend_ssa_escape_analysis(const zend_script *script, zend_op_array *op_array, zend_ssa *ssa);
typedef void (*zend_op_array_func_t)(zend_op_array *, void *context);
void zend_foreach_op_array(zend_script *script, zend_op_array_func_t func, void *context);
#endif

View file

@ -22,7 +22,6 @@
#include "zend_ssa.h"
#include "zend_dump.h"
#include "zend_inference.h"
#include "zend_worklist.h"
#include "Optimizer/zend_optimizer_internal.h"
static bool dominates(const zend_basic_block *blocks, int a, int b) {
@ -608,7 +607,7 @@ add_op1_def:
}
break;
case ZEND_ASSIGN_OBJ_REF:
if ((build_flags & ZEND_SSA_RC_INFERENCE) && opline->op1_type == IS_CV) {
if (opline->op1_type == IS_CV) {
ssa_ops[k].op1_def = ssa_vars_count;
var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
ssa_vars_count++;
@ -767,35 +766,6 @@ add_op1_def:
//NEW_SSA_VAR(opline->op1.var)
}
break;
case ZEND_FRAMELESS_ICALL_1:
case ZEND_FRAMELESS_ICALL_2:
case ZEND_FRAMELESS_ICALL_3: {
if ((build_flags & ZEND_SSA_RC_INFERENCE) && opline->op1_type == IS_CV) {
ssa_ops[k].op1_def = ssa_vars_count;
var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
ssa_vars_count++;
//NEW_SSA_VAR(opline->op1.var)
}
if ((build_flags & ZEND_SSA_RC_INFERENCE) && opline->op2_type == IS_CV) {
ssa_ops[k].op2_def = ssa_vars_count;
var[EX_VAR_TO_NUM(opline->op2.var)] = ssa_vars_count;
ssa_vars_count++;
//NEW_SSA_VAR(opline->op2.var)
}
if (opline->opcode == ZEND_FRAMELESS_ICALL_3) {
next = opline + 1;
if (next->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
ssa_ops[k + 1].op1_use = var[EX_VAR_TO_NUM(next->op1.var)];
//USE_SSA_VAR(op_array->last_var + next->op1.var);
if ((build_flags & ZEND_SSA_RC_INFERENCE) && next->op1_type == IS_CV) {
ssa_ops[k + 1].op1_def = ssa_vars_count;
var[EX_VAR_TO_NUM(next->op1.var)] = ssa_vars_count;
ssa_vars_count++;
//NEW_SSA_VAR(next->op1.var)
}
}
}
}
default:
break;
}
@ -817,7 +787,7 @@ ZEND_API int zend_ssa_rename_op(const zend_op_array *op_array, const zend_op *op
}
/* }}} */
static void zend_ssa_rename_in_block(const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, int *var, int n) /* {{{ */
static zend_result zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, int *var, int n) /* {{{ */
{
zend_basic_block *blocks = ssa->cfg.blocks;
zend_ssa_block *ssa_blocks = ssa->blocks;
@ -825,6 +795,15 @@ static void zend_ssa_rename_in_block(const zend_op_array *op_array, uint32_t bui
int ssa_vars_count = ssa->vars_count;
int i, j;
zend_op *opline, *end;
int *tmp = NULL;
ALLOCA_FLAG(use_heap = 0);
// FIXME: Can we optimize this copying out in some cases?
if (blocks[n].next_child >= 0) {
tmp = do_alloca(sizeof(int) * (op_array->last_var + op_array->T), use_heap);
memcpy(tmp, var, sizeof(int) * (op_array->last_var + op_array->T));
var = tmp;
}
if (ssa_blocks[n].phis) {
zend_ssa_phi *phi = ssa_blocks[n].phis;
@ -908,90 +887,22 @@ static void zend_ssa_rename_in_block(const zend_op_array *op_array, uint32_t bui
}
ssa->vars_count = ssa_vars_count;
}
/* }}} */
static zend_result zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa, int *var, int n)
{
/* The worklist contains block numbers, encoded as positive or negative value.
* Positive values indicate that the variable rename still needs to happen for the block.
* Negative values indicate the variable rename was done and all children were handled too.
* In that case, we will clean up.
* Because block 0 is valid, we bias the block numbers by adding 1 such that we can distinguish
* positive and negative values in all cases. */
zend_worklist_stack work;
ALLOCA_FLAG(work_use_heap);
ZEND_WORKLIST_STACK_ALLOCA(&work, ssa->cfg.blocks_count, work_use_heap);
zend_worklist_stack_push(&work, n + 1);
/* This is used to backtrack the right version of the renamed variables to use. */
ALLOCA_FLAG(save_vars_use_heap);
unsigned int save_vars_top = 0;
int **save_vars = do_alloca(sizeof(int *) * (ssa->cfg.blocks_count + 1), save_vars_use_heap);
save_vars[0] = var;
while (work.len) {
n = zend_worklist_stack_pop(&work);
/* Enter state: perform SSA variable rename */
if (n > 0) {
n--;
// FIXME: Can we optimize this copying out in some cases?
int *new_var;
if (ssa->cfg.blocks[n].next_child >= 0) {
new_var = emalloc(sizeof(int) * (op_array->last_var + op_array->T));
memcpy(new_var, save_vars[save_vars_top], sizeof(int) * (op_array->last_var + op_array->T));
save_vars[++save_vars_top] = new_var;
} else {
new_var = save_vars[save_vars_top];
}
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--;
}
}
j = blocks[n].children;
while (j >= 0) {
// FIXME: Tail call optimization?
if (zend_ssa_rename(op_array, build_flags, ssa, var, j) == FAILURE)
return FAILURE;
j = blocks[j].next_child;
}
free_alloca(save_vars, save_vars_use_heap);
ZEND_WORKLIST_STACK_FREE_ALLOCA(&work, work_use_heap);
if (tmp) {
free_alloca(tmp, use_heap);
}
return SUCCESS;
}
/* }}} */
ZEND_API zend_result zend_build_ssa(zend_arena **arena, const zend_script *script, const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa) /* {{{ */
{

View file

@ -67,7 +67,7 @@ struct _zend_ssa_phi {
int var; /* Original CV, VAR or TMP variable index */
int ssa_var; /* SSA variable index */
int block; /* current BB index */
bool has_range_constraint;
bool has_range_constraint : 1;
zend_ssa_phi **use_chains;
zend_ssa_phi *sym_use_chain;
int *sources; /* Array of SSA IDs that produce this var.
@ -112,8 +112,8 @@ typedef struct _zend_ssa_var {
zend_ssa_phi *definition_phi; /* phi that defines this value */
zend_ssa_phi *phi_use_chain; /* uses of this value in Phi, linked through use_chain */
zend_ssa_phi *sym_use_chain; /* uses of this value in Pi constraints */
bool no_val : 1; /* value doesn't matter (used as op1 in ZEND_ASSIGN) */
bool scc_entry : 1;
unsigned int no_val : 1; /* value doesn't matter (used as op1 in ZEND_ASSIGN) */
unsigned int scc_entry : 1;
unsigned int alias : 2; /* value may be changed indirectly */
unsigned int escape_state : 2;
} zend_ssa_var;

View file

@ -4,12 +4,13 @@ dnl
dnl ZEND_CHECK_FLOAT_PRECISION
dnl
dnl x87 floating point internal precision control checks
dnl See: https://wiki.php.net/rfc/rounding
dnl See: http://wiki.php.net/rfc/rounding
dnl
AC_DEFUN([ZEND_CHECK_FLOAT_PRECISION], [dnl
AC_CACHE_CHECK([for usable _FPU_SETCW],
[php_cv_have__fpu_setcw],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <fpu_control.h>], [dnl
AC_DEFUN([ZEND_CHECK_FLOAT_PRECISION],[
AC_MSG_CHECKING([for usable _FPU_SETCW])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <fpu_control.h>
]],[[
fpu_control_t fpu_oldcw, fpu_cw;
volatile double result;
double a = 2877.0;
@ -20,17 +21,18 @@ AC_CACHE_CHECK([for usable _FPU_SETCW],
_FPU_SETCW(fpu_cw);
result = a / b;
_FPU_SETCW(fpu_oldcw);
(void)result;
])],
[php_cv_have__fpu_setcw=yes],
[php_cv_have__fpu_setcw=no])])
AS_VAR_IF([php_cv_have__fpu_setcw], [yes],
[AC_DEFINE([HAVE__FPU_SETCW], [1],
[Define to 1 if _FPU_SETCW is present and usable.])])
]])],[ac_cfp_have__fpu_setcw=yes],[ac_cfp_have__fpu_setcw=no])
if test "$ac_cfp_have__fpu_setcw" = "yes" ; then
AC_DEFINE(HAVE__FPU_SETCW, 1, [whether _FPU_SETCW is present and usable])
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
AC_CACHE_CHECK([for usable fpsetprec],
[php_cv_have_fpsetprec],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <machine/ieeefp.h>], [dnl
AC_MSG_CHECKING([for usable fpsetprec])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <machine/ieeefp.h>
]],[[
fp_prec_t fpu_oldprec;
volatile double result;
double a = 2877.0;
@ -40,17 +42,18 @@ AC_CACHE_CHECK([for usable fpsetprec],
fpsetprec(FP_PD);
result = a / b;
fpsetprec(fpu_oldprec);
(void)result;
])],
[php_cv_have_fpsetprec=yes],
[php_cv_have_fpsetprec=no])])
AS_VAR_IF([php_cv_have_fpsetprec], [yes],
[AC_DEFINE([HAVE_FPSETPREC], [1],
[Define to 1 if fpsetprec is present and usable.])])
]])], [ac_cfp_have_fpsetprec=yes], [ac_cfp_have_fpsetprec=no])
if test "$ac_cfp_have_fpsetprec" = "yes" ; then
AC_DEFINE(HAVE_FPSETPREC, 1, [whether fpsetprec is present and usable])
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
AC_CACHE_CHECK([for usable _controlfp],
[php_cv_have__controlfp],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <float.h>], [dnl
AC_MSG_CHECKING([for usable _controlfp])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <float.h>
]],[[
unsigned int fpu_oldcw;
volatile double result;
double a = 2877.0;
@ -60,17 +63,18 @@ AC_CACHE_CHECK([for usable _controlfp],
_controlfp(_PC_53, _MCW_PC);
result = a / b;
_controlfp(fpu_oldcw, _MCW_PC);
(void)result;
])],
[php_cv_have__controlfp=yes],
[php_cv_have__controlfp=no])])
AS_VAR_IF([php_cv_have__controlfp], [yes],
[AC_DEFINE([HAVE__CONTROLFP], [1],
[Define to 1 if _controlfp is present and usable.])])
]])], [ac_cfp_have__controlfp=yes], [ac_cfp_have__controlfp=no])
if test "$ac_cfp_have__controlfp" = "yes" ; then
AC_DEFINE(HAVE__CONTROLFP, 1, [whether _controlfp is present usable])
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
AC_CACHE_CHECK([for usable _controlfp_s],
[php_cv_have__controlfp_s],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <float.h>], [dnl
AC_MSG_CHECKING([for usable _controlfp_s])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <float.h>
]],[[
unsigned int fpu_oldcw, fpu_cw;
volatile double result;
double a = 2877.0;
@ -81,17 +85,18 @@ AC_CACHE_CHECK([for usable _controlfp_s],
_controlfp_s(&fpu_cw, _PC_53, _MCW_PC);
result = a / b;
_controlfp_s(&fpu_cw, fpu_oldcw, _MCW_PC);
(void)result;
])],
[php_cv_have__controlfp_s=yes],
[php_cv_have__controlfp_s=no])])
AS_VAR_IF([php_cv_have__controlfp_s], [yes],
[AC_DEFINE([HAVE__CONTROLFP_S], [1],
[Define to 1 if _controlfp_s is present and usable.])])
]])], [ac_cfp_have__controlfp_s=yes], [ac_cfp_have__controlfp_s=no])
if test "$ac_cfp_have__controlfp_s" = "yes" ; then
AC_DEFINE(HAVE__CONTROLFP_S, 1, [whether _controlfp_s is present and usable])
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
AC_CACHE_CHECK([whether FPU control word can be manipulated by inline assembler],
[php_cv_have_fpu_inline_asm_x86],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([], [dnl
AC_MSG_CHECKING([whether FPU control word can be manipulated by inline assembler])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
/* nothing */
]],[[
unsigned int oldcw, cw;
volatile double result;
double a = 2877.0;
@ -100,185 +105,235 @@ AC_CACHE_CHECK([whether FPU control word can be manipulated by inline assembler]
__asm__ __volatile__ ("fnstcw %0" : "=m" (*&oldcw));
cw = (oldcw & ~0x0 & ~0x300) | 0x200;
__asm__ __volatile__ ("fldcw %0" : : "m" (*&cw));
result = a / b;
__asm__ __volatile__ ("fldcw %0" : : "m" (*&oldcw));
(void)result;
])],
[php_cv_have_fpu_inline_asm_x86=yes],
[php_cv_have_fpu_inline_asm_x86=no])])
AS_VAR_IF([php_cv_have_fpu_inline_asm_x86], [yes],
[AC_DEFINE([HAVE_FPU_INLINE_ASM_X86], [1],
[Define to 1 if FPU control word can be manipulated by inline assembler.])])
]])], [ac_cfp_have_fpu_inline_asm_x86=yes], [ac_cfp_have_fpu_inline_asm_x86=no])
if test "$ac_cfp_have_fpu_inline_asm_x86" = "yes" ; then
AC_DEFINE(HAVE_FPU_INLINE_ASM_X86, 1, [whether FPU control word can be manipulated by inline assembler])
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
])
dnl
dnl ZEND_DLSYM_CHECK
dnl LIBZEND_BASIC_CHECKS
dnl
dnl Basic checks specific for the Zend engine library.
dnl
AC_DEFUN([LIBZEND_BASIC_CHECKS],[
AC_REQUIRE([AC_PROG_CC])
AC_CHECK_HEADERS([cpuid.h])
dnl
dnl LIBZEND_DLSYM_CHECK
dnl
dnl Ugly hack to check if dlsym() requires a leading underscore in symbol name.
dnl
AC_DEFUN([ZEND_DLSYM_CHECK], [dnl
AC_DEFUN([LIBZEND_DLSYM_CHECK],[
AC_MSG_CHECKING([whether dlsym() requires a leading underscore in symbol names])
_LT_AC_TRY_DLOPEN_SELF([AC_MSG_RESULT([no])], [
AC_MSG_RESULT([yes])
AC_DEFINE([DLSYM_NEEDS_UNDERSCORE], [1],
[Define to 1 if 'dlsym()' requires a leading underscore in symbol names.])
], [AC_MSG_RESULT([no])], [])
_LT_AC_TRY_DLOPEN_SELF([
AC_MSG_RESULT(no)
], [
AC_MSG_RESULT(yes)
AC_DEFINE(DLSYM_NEEDS_UNDERSCORE, 1, [Define if dlsym() requires a leading underscore in symbol names. ])
], [
AC_MSG_RESULT(no)
], [])
])
dnl
dnl ZEND_INIT
dnl
dnl Configure checks and initialization specific for the Zend engine library.
dnl
AC_DEFUN([ZEND_INIT], [dnl
AC_REQUIRE([AC_PROG_CC])
dnl Checks for library functions.
AC_CHECK_FUNCS(getpid kill sigsetjmp pthread_getattr_np pthread_attr_get_np pthread_get_stackaddr_np pthread_attr_getstack pthread_stackseg_np gettid)
AC_CHECK_HEADERS(m4_normalize([
cpuid.h
libproc.h
]))
dnl Test whether the stack grows downwards
dnl Assumes contiguous stack
AC_MSG_CHECKING(whether the stack grows downwards)
dnl Check for library functions.
AC_CHECK_FUNCS(m4_normalize([
getpid
gettid
kill
mremap
pthread_attr_get_np
pthread_attr_getstack
pthread_get_stackaddr_np
pthread_getattr_np
pthread_stackseg_np
strnlen
]))
AC_CHECK_DECL([clock_gettime_nsec_np],
[AC_DEFINE([HAVE_CLOCK_GETTIME_NSEC_NP], [1],
[Define to 1 if you have the declaration of 'clock_gettime_nsec_np'.])],,
[#include <time.h>])
dnl
dnl Check for sigsetjmp. If sigsetjmp is defined as a macro, use AC_CHECK_DECL
dnl as a fallback since AC_CHECK_FUNC cannot detect macros.
dnl
AC_CHECK_FUNC([sigsetjmp],,
[AC_CHECK_DECL([sigsetjmp],,
[AC_MSG_FAILURE([Required sigsetjmp not found.])],
[#include <setjmp.h>])])
ZEND_CHECK_STACK_DIRECTION
ZEND_CHECK_FLOAT_PRECISION
ZEND_DLSYM_CHECK
ZEND_CHECK_GLOBAL_REGISTER_VARIABLES
ZEND_CHECK_CPUID_COUNT
AC_MSG_CHECKING([whether to enable thread safety])
AC_MSG_RESULT([$ZEND_ZTS])
AS_VAR_IF([ZEND_ZTS], [yes], [
AC_DEFINE([ZTS], [1], [Define to 1 if thread safety (ZTS) is enabled.])
AS_VAR_APPEND([CFLAGS], [" -DZTS"])
])
AC_MSG_CHECKING([whether to enable Zend debugging])
AC_MSG_RESULT([$ZEND_DEBUG])
AH_TEMPLATE([ZEND_DEBUG],
[Define to 1 if debugging is enabled, and to 0 if not.])
AS_VAR_IF([ZEND_DEBUG], [yes], [
AC_DEFINE([ZEND_DEBUG], [1])
echo " $CFLAGS" | grep ' -g' >/dev/null || CFLAGS="$CFLAGS -g"
], [AC_DEFINE([ZEND_DEBUG], [0])])
AS_VAR_IF([GCC], [yes],
[CFLAGS="-Wall -Wextra -Wno-unused-parameter -Wno-sign-compare $CFLAGS"])
dnl Check if compiler supports -Wno-clobbered (only GCC).
AX_CHECK_COMPILE_FLAG([-Wno-clobbered],
[CFLAGS="-Wno-clobbered $CFLAGS"])
dnl Check for support for implicit fallthrough level 1, also add after previous
dnl CFLAGS as level 3 is enabled in -Wextra.
AX_CHECK_COMPILE_FLAG([-Wimplicit-fallthrough=1],
[CFLAGS="$CFLAGS -Wimplicit-fallthrough=1"])
AX_CHECK_COMPILE_FLAG([-Wduplicated-cond],
[CFLAGS="-Wduplicated-cond $CFLAGS"])
AX_CHECK_COMPILE_FLAG([-Wlogical-op],
[CFLAGS="-Wlogical-op $CFLAGS"])
AX_CHECK_COMPILE_FLAG([-Wformat-truncation],
[CFLAGS="-Wformat-truncation $CFLAGS"])
AX_CHECK_COMPILE_FLAG([-Wstrict-prototypes],
[CFLAGS="-Wstrict-prototypes $CFLAGS"])
AX_CHECK_COMPILE_FLAG([-fno-common],
[CFLAGS="-fno-common $CFLAGS"])
ZEND_CHECK_ALIGNMENT
ZEND_CHECK_SIGNALS
ZEND_CHECK_MAX_EXECUTION_TIMERS
])
dnl
dnl ZEND_CHECK_STACK_DIRECTION
dnl
dnl Check whether the stack grows downwards, assumes contiguous stack.
dnl
AC_DEFUN([ZEND_CHECK_STACK_DIRECTION],
[AC_CACHE_CHECK([whether the stack grows downwards],
[php_cv_have_stack_limit],
[AC_RUN_IFELSE([AC_LANG_SOURCE([dnl
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdint.h>
#ifdef __has_builtin
# if __has_builtin(__builtin_frame_address)
# define builtin_frame_address __builtin_frame_address(0)
# endif
#endif
int (*volatile f)(uintptr_t);
int stack_grows_downwards(uintptr_t arg) {
#ifdef builtin_frame_address
uintptr_t addr = (uintptr_t)builtin_frame_address;
#else
int local;
uintptr_t addr = (uintptr_t)&local;
#endif
return addr < arg;
int local;
return (uintptr_t)&local < arg;
}
int main(void) {
#ifdef builtin_frame_address
uintptr_t addr = (uintptr_t)builtin_frame_address;
#else
int local;
uintptr_t addr = (uintptr_t)&local;
#endif
int local;
f = stack_grows_downwards;
return f(addr) ? 0 : 1;
}])],
[php_cv_have_stack_limit=yes],
[php_cv_have_stack_limit=no],
[php_cv_have_stack_limit=no])])
AS_VAR_IF([php_cv_have_stack_limit], [yes],
[AC_DEFINE([ZEND_CHECK_STACK_LIMIT], [1],
[Define to 1 if checking the stack limit is supported.])])
f = stack_grows_downwards;
return f((uintptr_t)&local) ? 0 : 1;
}
]])], [
AC_DEFINE([ZEND_CHECK_STACK_LIMIT], 1, [Define if checking the stack limit is supported])
AC_MSG_RESULT(yes)
], [
AC_MSG_RESULT(no)
], [
AC_MSG_RESULT(no)
])
ZEND_CHECK_FLOAT_PRECISION
])
dnl
dnl ZEND_CHECK_GLOBAL_REGISTER_VARIABLES
dnl LIBZEND_OTHER_CHECKS
dnl
dnl Check whether to enable global register variables if supported.
dnl
AC_DEFUN([ZEND_CHECK_GLOBAL_REGISTER_VARIABLES], [dnl
AC_DEFUN([LIBZEND_OTHER_CHECKS],[
AC_MSG_CHECKING(whether to enable thread-safety)
AC_MSG_RESULT($ZEND_ZTS)
AC_MSG_CHECKING(whether to enable Zend debugging)
AC_MSG_RESULT($ZEND_DEBUG)
if test "$ZEND_DEBUG" = "yes"; then
AC_DEFINE(ZEND_DEBUG,1,[ ])
echo " $CFLAGS" | grep ' -g' >/dev/null || DEBUG_CFLAGS="-g"
if test "$CFLAGS" = "-g -O2"; then
CFLAGS=-g
fi
else
AC_DEFINE(ZEND_DEBUG,0,[ ])
fi
test -n "$GCC" && CFLAGS="-Wall -Wextra -Wno-unused-parameter -Wno-sign-compare $CFLAGS"
dnl Check if compiler supports -Wno-clobbered (only GCC)
AX_CHECK_COMPILE_FLAG([-Wno-clobbered], CFLAGS="-Wno-clobbered $CFLAGS", , [-Werror])
dnl Check for support for implicit fallthrough level 1, also add after previous CFLAGS as level 3 is enabled in -Wextra
AX_CHECK_COMPILE_FLAG([-Wimplicit-fallthrough=1], CFLAGS="$CFLAGS -Wimplicit-fallthrough=1", , [-Werror])
AX_CHECK_COMPILE_FLAG([-Wduplicated-cond], CFLAGS="-Wduplicated-cond $CFLAGS", , [-Werror])
AX_CHECK_COMPILE_FLAG([-Wlogical-op], CFLAGS="-Wlogical-op $CFLAGS", , [-Werror])
AX_CHECK_COMPILE_FLAG([-Wformat-truncation], CFLAGS="-Wformat-truncation $CFLAGS", , [-Werror])
AX_CHECK_COMPILE_FLAG([-Wstrict-prototypes], CFLAGS="-Wstrict-prototypes $CFLAGS", , [-Werror])
AX_CHECK_COMPILE_FLAG([-fno-common], CFLAGS="-fno-common $CFLAGS", , [-Werror])
test -n "$DEBUG_CFLAGS" && CFLAGS="$CFLAGS $DEBUG_CFLAGS"
if test "$ZEND_ZTS" = "yes"; then
AC_DEFINE(ZTS,1,[ ])
CFLAGS="$CFLAGS -DZTS"
fi
AC_C_INLINE
AC_MSG_CHECKING(target system is Darwin)
if echo "$target" | grep "darwin" > /dev/null; then
AC_DEFINE([DARWIN], 1, [Define if the target system is darwin])
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
dnl Test and set the alignment define for ZEND_MM. This also does the
dnl logarithmic test for ZEND_MM.
AC_MSG_CHECKING(for MM alignment and log values)
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
#include <stdlib.h>
typedef union _mm_align_test {
void *ptr;
double dbl;
long lng;
} mm_align_test;
#if (defined (__GNUC__) && __GNUC__ >= 2)
#define ZEND_MM_ALIGNMENT (__alignof__ (mm_align_test))
#else
#define ZEND_MM_ALIGNMENT (sizeof(mm_align_test))
#endif
int main(void)
{
size_t i = ZEND_MM_ALIGNMENT;
int zeros = 0;
FILE *fp;
while (i & ~0x1) {
zeros++;
i = i >> 1;
}
fp = fopen("conftest.zend", "w");
fprintf(fp, "(size_t)%zu (size_t)%d %d\n", ZEND_MM_ALIGNMENT, zeros, ZEND_MM_ALIGNMENT < 4);
fclose(fp);
return 0;
}
]])], [
LIBZEND_MM_ALIGN=`cat conftest.zend | cut -d ' ' -f 1`
LIBZEND_MM_ALIGN_LOG2=`cat conftest.zend | cut -d ' ' -f 2`
LIBZEND_MM_NEED_EIGHT_BYTE_REALIGNMENT=`cat conftest.zend | cut -d ' ' -f 3`
AC_DEFINE_UNQUOTED(ZEND_MM_ALIGNMENT, $LIBZEND_MM_ALIGN, [ ])
AC_DEFINE_UNQUOTED(ZEND_MM_ALIGNMENT_LOG2, $LIBZEND_MM_ALIGN_LOG2, [ ])
AC_DEFINE_UNQUOTED(ZEND_MM_NEED_EIGHT_BYTE_REALIGNMENT, $LIBZEND_MM_NEED_EIGHT_BYTE_REALIGNMENT, [ ])
], [], [
dnl Cross compilation needs something here.
AC_DEFINE(ZEND_MM_ALIGNMENT, 8, [ ])
AC_DEFINE(ZEND_MM_ALIGNMENT_LOG2, 3, [ ])
AC_DEFINE(ZEND_MM_NEED_EIGHT_BYTE_REALIGNMENT, 0, [ ])
])
AC_MSG_RESULT(done)
AC_CHECK_FUNCS(mremap)
AC_ARG_ENABLE([zend-signals],
[AS_HELP_STRING([--disable-zend-signals],
[whether to enable zend signal handling])],
[ZEND_SIGNALS=$enableval],
[ZEND_SIGNALS=yes])
AC_CHECK_FUNCS([sigaction], [], [
ZEND_SIGNALS=no
])
if test "$ZEND_SIGNALS" = "yes"; then
AC_DEFINE(ZEND_SIGNALS, 1, [Use zend signal handling])
CFLAGS="$CFLAGS -DZEND_SIGNALS"
fi
AC_MSG_CHECKING(whether to enable zend signal handling)
AC_MSG_RESULT($ZEND_SIGNALS)
dnl Don't enable Zend Max Execution Timers by default until PHP 8.3 to not break the ABI
AC_ARG_ENABLE([zend-max-execution-timers],
[AS_HELP_STRING([--enable-zend-max-execution-timers],
[whether to enable zend max execution timers])],
[ZEND_MAX_EXECUTION_TIMERS=$enableval],
[ZEND_MAX_EXECUTION_TIMERS=$ZEND_ZTS])
AS_CASE(["$host_alias"], [*linux*], [], [ZEND_MAX_EXECUTION_TIMERS='no'])
PHP_CHECK_FUNC(timer_create, rt)
if test "$ac_cv_func_timer_create" != "yes"; then
ZEND_MAX_EXECUTION_TIMERS='no'
fi
if test "$ZEND_MAX_EXECUTION_TIMERS" = "yes"; then
AC_DEFINE(ZEND_MAX_EXECUTION_TIMERS, 1, [Use zend max execution timers])
CFLAGS="$CFLAGS -DZEND_MAX_EXECUTION_TIMERS"
fi
AC_MSG_CHECKING(whether to enable zend max execution timers)
AC_MSG_RESULT($ZEND_MAX_EXECUTION_TIMERS)
])
AC_ARG_ENABLE([gcc-global-regs],
[AS_HELP_STRING([--disable-gcc-global-regs],
[Disable GCC global register variables])],
[whether to enable GCC global register variables])],
[ZEND_GCC_GLOBAL_REGS=$enableval],
[ZEND_GCC_GLOBAL_REGS=yes])
AS_VAR_IF([ZEND_GCC_GLOBAL_REGS], [no],,
[AC_CACHE_CHECK([whether system supports global register variables],
[php_cv_have_global_register_vars],
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
AC_MSG_CHECKING(for global register variables support)
if test "$ZEND_GCC_GLOBAL_REGS" != "no"; then
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#if defined(__GNUC__)
# define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
#else
@ -309,158 +364,38 @@ typedef int (*opcode_handler_t)(void);
register void *FP __asm__(ZEND_VM_FP_GLOBAL_REG);
register const opcode_handler_t *IP __asm__(ZEND_VM_IP_GLOBAL_REG);
int emu(const opcode_handler_t *ip, void *fp) {
const opcode_handler_t *orig_ip = IP;
void *orig_fp = FP;
IP = ip;
FP = fp;
while ((*ip)());
FP = orig_fp;
IP = orig_ip;
}], [])],
[php_cv_have_global_register_vars=yes],
[php_cv_have_global_register_vars=no])
])
AS_VAR_IF([php_cv_have_global_register_vars], [yes],
[AC_DEFINE([HAVE_GCC_GLOBAL_REGS], [1],
[Define to 1 if the target system has support for global register
variables.])],
[ZEND_GCC_GLOBAL_REGS=no])
])
AC_MSG_CHECKING([whether to enable global register variables support])
AC_MSG_RESULT([$ZEND_GCC_GLOBAL_REGS])
])
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;
const opcode_handler_t *orig_ip = IP;
void *orig_fp = FP;
IP = ip;
FP = fp;
while ((*ip)());
FP = orig_fp;
IP = orig_ip;
}
])],
[php_cv_align_mm=$(cat conftest.zend)],
[php_cv_align_mm=failed],
[php_cv_align_mm="(size_t)8 (size_t)3 0"])])
AS_VAR_IF([php_cv_align_mm], [failed],
[AC_MSG_FAILURE([ZEND_MM alignment defines failed.])],
[zend_mm_alignment=$(echo $php_cv_align_mm | cut -d ' ' -f 1)
zend_mm_alignment_log2=$(echo $php_cv_align_mm | cut -d ' ' -f 2)
zend_mm_8byte_realign=$(echo $php_cv_align_mm | cut -d ' ' -f 3)
AC_DEFINE_UNQUOTED([ZEND_MM_ALIGNMENT],
[$zend_mm_alignment],
[Number of bytes for the ZEND_MM alignment.])
AC_DEFINE_UNQUOTED([ZEND_MM_ALIGNMENT_LOG2],
[$zend_mm_alignment_log2],
[Number of bytes for the logarithmic ZEND_MM alignment.])
AC_DEFINE_UNQUOTED([ZEND_MM_NEED_EIGHT_BYTE_REALIGNMENT],
[$zend_mm_8byte_realign],
[Define to 1 if ZEND_MM needs 8-byte realignment, and to 0 if not.])
])
])
]], [[
]])], [
ZEND_GCC_GLOBAL_REGS=yes
], [
ZEND_GCC_GLOBAL_REGS=no
])
fi
if test "$ZEND_GCC_GLOBAL_REGS" = "yes"; then
AC_DEFINE([HAVE_GCC_GLOBAL_REGS], 1, [Define if the target system has support for global register variables])
fi
AC_MSG_RESULT($ZEND_GCC_GLOBAL_REGS)
dnl
dnl ZEND_CHECK_SIGNALS
dnl
dnl Check whether to enable Zend signal handling if supported by the system.
dnl
AC_DEFUN([ZEND_CHECK_SIGNALS], [dnl
AC_ARG_ENABLE([zend-signals],
[AS_HELP_STRING([--disable-zend-signals],
[Disable Zend signal handling])],
[ZEND_SIGNALS=$enableval],
[ZEND_SIGNALS=yes])
AC_CHECK_FUNCS([sigaction],, [ZEND_SIGNALS=no])
AS_VAR_IF([ZEND_SIGNALS], [yes],
[AC_DEFINE([ZEND_SIGNALS], [1],
[Define to 1 if Zend signal handling is supported and enabled.])
AS_VAR_APPEND([CFLAGS], [" -DZEND_SIGNALS"])])
AC_MSG_CHECKING([whether to enable Zend signal handling])
AC_MSG_RESULT([$ZEND_SIGNALS])
])
dnl
dnl ZEND_CHECK_MAX_EXECUTION_TIMERS
dnl
dnl Check whether to enable Zend max execution timers.
dnl
AC_DEFUN([ZEND_CHECK_MAX_EXECUTION_TIMERS], [dnl
AC_ARG_ENABLE([zend-max-execution-timers],
[AS_HELP_STRING([--enable-zend-max-execution-timers],
[Enable Zend max execution timers; when building with thread safety
(--enable-zts), they are automatically enabled by default based on the
system support])],
[ZEND_MAX_EXECUTION_TIMERS=$enableval],
[ZEND_MAX_EXECUTION_TIMERS=$ZEND_ZTS])
AS_CASE([$host_alias], [*linux*|*freebsd*],,
[ZEND_MAX_EXECUTION_TIMERS=no])
AS_VAR_IF([ZEND_MAX_EXECUTION_TIMERS], [yes],
[AC_SEARCH_LIBS([timer_create], [rt],,
[ZEND_MAX_EXECUTION_TIMERS=no])])
AS_VAR_IF([ZEND_MAX_EXECUTION_TIMERS], [yes],
[AC_DEFINE([ZEND_MAX_EXECUTION_TIMERS], [1],
[Define to 1 if Zend max execution timers are supported and enabled.])
AS_VAR_APPEND([CFLAGS], [" -DZEND_MAX_EXECUTION_TIMERS"])])
AC_MSG_CHECKING([whether to enable Zend max execution timers])
AC_MSG_RESULT([$ZEND_MAX_EXECUTION_TIMERS])
])
dnl Check whether __cpuid_count is available.
AC_CACHE_CHECK(whether __cpuid_count is available, ac_cv_cpuid_count_available, [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <cpuid.h>
]], [[
unsigned eax, ebx, ecx, edx;
__cpuid_count(0, 0, eax, ebx, ecx, edx);
]])], [
ac_cv_cpuid_count_available=yes
], [
ac_cv_cpuid_count_available=no
])])
if test "$ac_cv_cpuid_count_available" = "yes"; then
AC_DEFINE([HAVE_CPUID_COUNT], 1, [whether __cpuid_count is available])
fi

View file

@ -1,133 +1,133 @@
; Copyright Edward Nevill + Oliver Kowalke 2015
; 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| *
;* ------------------------------------------------- *
;* | d8 | d9 | d10 | d11 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
;* ------------------------------------------------- *
;* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
;* ------------------------------------------------- *
;* | d12 | d13 | d14 | d15 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
;* ------------------------------------------------- *
;* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
;* ------------------------------------------------- *
;* | x19 | x20 | x21 | x22 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
;* ------------------------------------------------- *
;* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
;* ------------------------------------------------- *
;* | x23 | x24 | x25 | x26 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
;* ------------------------------------------------- *
;* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| *
;* ------------------------------------------------- *
;* | x27 | x28 | FP | LR | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
;* ------------------------------------------------- *
;* | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| *
;* ------------------------------------------------- *
;* | fiber data| base | limit | dealloc | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 48 | 49 | 50 | 51 | | | *
;* ------------------------------------------------- *
;* | 0xc0| 0xc4| 0xc8| 0xcc| | | *
;* ------------------------------------------------- *
;* | PC | align | | | *
;* ------------------------------------------------- *
;* *
;*******************************************************
AREA |.text|, CODE, READONLY, ALIGN=4, CODEALIGN
EXPORT jump_fcontext
jump_fcontext proc
; prepare stack for GP + FPU
sub sp, sp, #0xd0
; save d8 - d15
stp d8, d9, [sp, #0x00]
stp d10, d11, [sp, #0x10]
stp d12, d13, [sp, #0x20]
stp d14, d15, [sp, #0x30]
; save x19-x30
stp x19, x20, [sp, #0x40]
stp x21, x22, [sp, #0x50]
stp x23, x24, [sp, #0x60]
stp x25, x26, [sp, #0x70]
stp x27, x28, [sp, #0x80]
stp x29, x30, [sp, #0x90]
; save LR as PC
str x30, [sp, #0xc0]
; save current stack base and limit
ldp x5, x6, [x18, #0x08] ; TeStackBase and TeStackLimit at ksarm64.h
stp x5, x6, [sp, #0xa0]
; save current fiber data and deallocation stack
ldr x5, [x18, #0x1478] ; TeDeallocationStack at ksarm64.h
ldr x6, [x18, #0x20] ; TeFiberData at ksarm64.h
stp x5, x6, [sp, #0xb0]
; store RSP (pointing to context-data) in X0
mov x4, sp
; restore RSP (pointing to context-data) from X1
mov sp, x0
; restore stack base and limit
ldp x5, x6, [sp, #0xa0]
stp x5, x6, [x18, #0x08] ; TeStackBase and TeStackLimit at ksarm64.h
; restore fiber data and deallocation stack
ldp x5, x6, [sp, #0xb0]
str x5, [x18, #0x1478] ; TeDeallocationStack at ksarm64.h
str x6, [x18, #0x20] ; TeFiberData at ksarm64.h
; load d8 - d15
ldp d8, d9, [sp, #0x00]
ldp d10, d11, [sp, #0x10]
ldp d12, d13, [sp, #0x20]
ldp d14, d15, [sp, #0x30]
; load x19-x30
ldp x19, x20, [sp, #0x40]
ldp x21, x22, [sp, #0x50]
ldp x23, x24, [sp, #0x60]
ldp x25, x26, [sp, #0x70]
ldp x27, x28, [sp, #0x80]
ldp x29, x30, [sp, #0x90]
; return transfer_t from jump
; pass transfer_t as first arg in context function
; X0 == FCTX, X1 == DATA
mov x0, x4
; load pc
ldr x4, [sp, #0xc0]
; restore stack from GP + FPU
add sp, sp, #0xd0
ret x4
ENDP
; Copyright Edward Nevill + Oliver Kowalke 2015
; 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| *
;* ------------------------------------------------- *
;* | d8 | d9 | d10 | d11 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
;* ------------------------------------------------- *
;* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
;* ------------------------------------------------- *
;* | d12 | d13 | d14 | d15 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
;* ------------------------------------------------- *
;* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
;* ------------------------------------------------- *
;* | x19 | x20 | x21 | x22 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
;* ------------------------------------------------- *
;* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
;* ------------------------------------------------- *
;* | x23 | x24 | x25 | x26 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
;* ------------------------------------------------- *
;* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| *
;* ------------------------------------------------- *
;* | x27 | x28 | FP | LR | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
;* ------------------------------------------------- *
;* | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| *
;* ------------------------------------------------- *
;* | fiber data| base | limit | dealloc | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 48 | 49 | 50 | 51 | | | *
;* ------------------------------------------------- *
;* | 0xc0| 0xc4| 0xc8| 0xcc| | | *
;* ------------------------------------------------- *
;* | PC | align | | | *
;* ------------------------------------------------- *
;* *
;*******************************************************
AREA |.text|, CODE, READONLY, ALIGN=4, CODEALIGN
EXPORT jump_fcontext
jump_fcontext proc
; prepare stack for GP + FPU
sub sp, sp, #0xd0
; save d8 - d15
stp d8, d9, [sp, #0x00]
stp d10, d11, [sp, #0x10]
stp d12, d13, [sp, #0x20]
stp d14, d15, [sp, #0x30]
; save x19-x30
stp x19, x20, [sp, #0x40]
stp x21, x22, [sp, #0x50]
stp x23, x24, [sp, #0x60]
stp x25, x26, [sp, #0x70]
stp x27, x28, [sp, #0x80]
stp x29, x30, [sp, #0x90]
; save LR as PC
str x30, [sp, #0xc0]
; save current stack base and limit
ldp x5, x6, [x18, #0x08] ; TeStackBase and TeStackLimit at ksarm64.h
stp x5, x6, [sp, #0xa0]
; save current fiber data and deallocation stack
ldr x5, [x18, #0x1478] ; TeDeallocationStack at ksarm64.h
ldr x6, [x18, #0x20] ; TeFiberData at ksarm64.h
stp x5, x6, [sp, #0xb0]
; store RSP (pointing to context-data) in X0
mov x4, sp
; restore RSP (pointing to context-data) from X1
mov sp, x0
; restore stack base and limit
ldp x5, x6, [sp, #0xa0]
stp x5, x6, [x18, #0x08] ; TeStackBase and TeStackLimit at ksarm64.h
; restore fiber data and deallocation stack
ldp x5, x6, [sp, #0xb0]
str x5, [x18, #0x1478] ; TeDeallocationStack at ksarm64.h
str x6, [x18, #0x20] ; TeFiberData at ksarm64.h
; load d8 - d15
ldp d8, d9, [sp, #0x00]
ldp d10, d11, [sp, #0x10]
ldp d12, d13, [sp, #0x20]
ldp d14, d15, [sp, #0x30]
; load x19-x30
ldp x19, x20, [sp, #0x40]
ldp x21, x22, [sp, #0x50]
ldp x23, x24, [sp, #0x60]
ldp x25, x26, [sp, #0x70]
ldp x27, x28, [sp, #0x80]
ldp x29, x30, [sp, #0x90]
; return transfer_t from jump
; pass transfer_t as first arg in context function
; X0 == FCTX, X1 == DATA
mov x0, x4
; load pc
ldr x4, [sp, #0xc0]
; restore stack from GP + FPU
add sp, sp, #0xd0
ret x4
ENDP
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"
.text
.globl jump_fcontext
@ -95,5 +91,3 @@ jump_fcontext:
/* Mark that we don't need executable stack. */
.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__
# include "jump_i386_sysv_elf_gas.S"
# if defined __CET__
# include <cet.h>
# define SHSTK_ENABLED (__CET__ & 0x2)
# define BOOST_CONTEXT_SHADOW_STACK (SHSTK_ENABLED && SHADOW_STACK_SYSCALL)
# else
# if defined __CET__
# include <cet.h>
# define SHSTK_ENABLED (__CET__ & 0x2)
# define BOOST_CONTEXT_SHADOW_STACK (SHSTK_ENABLED && SHADOW_STACK_SYSCALL)
# else
# define _CET_ENDBR
# endif
# define _CET_ENDBR
# endif
.file "jump_x86_64_sysv_elf_gas.S"
.text
.globl jump_fcontext
@ -151,4 +148,3 @@ jump_fcontext:
/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits
# endif

View file

@ -1,107 +1,107 @@
; Copyright Edward Nevill + Oliver Kowalke 2015
; 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| *
;* ------------------------------------------------- *
;* | d8 | d9 | d10 | d11 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
;* ------------------------------------------------- *
;* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
;* ------------------------------------------------- *
;* | d12 | d13 | d14 | d15 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
;* ------------------------------------------------- *
;* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
;* ------------------------------------------------- *
;* | x19 | x20 | x21 | x22 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
;* ------------------------------------------------- *
;* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
;* ------------------------------------------------- *
;* | x23 | x24 | x25 | x26 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
;* ------------------------------------------------- *
;* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| *
;* ------------------------------------------------- *
;* | x27 | x28 | FP | LR | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
;* ------------------------------------------------- *
;* | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| *
;* ------------------------------------------------- *
;* | base | limit | dealloc | fiber data| *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 48 | 49 | 50 | 51 | | | *
;* ------------------------------------------------- *
;* | 0xc0| 0xc4| 0xc8| 0xcc| | | *
;* ------------------------------------------------- *
;* | PC | align | | | *
;* ------------------------------------------------- *
;* *
;*******************************************************
AREA |.text|, CODE, READONLY, ALIGN=4, CODEALIGN
EXPORT make_fcontext
IMPORT _exit
make_fcontext proc
; save stack top address to x3
mov x3, x0
; shift address in x0 (allocated stack) to lower 16 byte boundary
and x0, x0, ~0xF
; reserve space for context-data on context-stack
sub x0, x0, #0xd0
; save top address of context_stack as 'base'
str x3, [x0, #0xa0]
; save bottom address of context-stack as 'limit' and 'dealloction stack'
sub x3, x3, x1
stp x3, x3, [x0, #0xa8]
; save 0 as 'fiber data'
str xzr, [x0, #0xb8]
; third arg of make_fcontext() == address of context-function
; store address as x19 for trampoline
str x2, [x0, #0x40]
; store trampoline address as pc
adr x2, trampoline
str x2, [x0, #0xc0]
; save address of finish as return-address for context-function
; will be entered after context-function returns (LR register)
adr x1, finish
str x1, [x0, #0x98]
ret x30 ; return pointer to context-data (x0)
trampoline
stp fp, lr, [sp, #-0x10]!
mov fp, sp
blr x19
finish
; exit code is zero
mov x0, #0
; exit application
bl _exit
ENDP
END
; Copyright Edward Nevill + Oliver Kowalke 2015
; 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| *
;* ------------------------------------------------- *
;* | d8 | d9 | d10 | d11 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
;* ------------------------------------------------- *
;* | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| *
;* ------------------------------------------------- *
;* | d12 | d13 | d14 | d15 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | *
;* ------------------------------------------------- *
;* | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| *
;* ------------------------------------------------- *
;* | x19 | x20 | x21 | x22 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | *
;* ------------------------------------------------- *
;* | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| *
;* ------------------------------------------------- *
;* | x23 | x24 | x25 | x26 | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | *
;* ------------------------------------------------- *
;* | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| *
;* ------------------------------------------------- *
;* | x27 | x28 | FP | LR | *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | *
;* ------------------------------------------------- *
;* | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| *
;* ------------------------------------------------- *
;* | base | limit | dealloc | fiber data| *
;* ------------------------------------------------- *
;* ------------------------------------------------- *
;* | 48 | 49 | 50 | 51 | | | *
;* ------------------------------------------------- *
;* | 0xc0| 0xc4| 0xc8| 0xcc| | | *
;* ------------------------------------------------- *
;* | PC | align | | | *
;* ------------------------------------------------- *
;* *
;*******************************************************
AREA |.text|, CODE, READONLY, ALIGN=4, CODEALIGN
EXPORT make_fcontext
IMPORT _exit
make_fcontext proc
; save stack top address to x3
mov x3, x0
; shift address in x0 (allocated stack) to lower 16 byte boundary
and x0, x0, ~0xF
; reserve space for context-data on context-stack
sub x0, x0, #0xd0
; save top address of context_stack as 'base'
str x3, [x0, #0xa0]
; save bottom address of context-stack as 'limit' and 'dealloction stack'
sub x3, x3, x1
stp x3, x3, [x0, #0xa8]
; save 0 as 'fiber data'
str xzr, [x0, #0xb8]
; third arg of make_fcontext() == address of context-function
; store address as x19 for trampoline
str x2, [x0, #0x40]
; store trampoline address as pc
adr x2, trampoline
str x2, [x0, #0xc0]
; save address of finish as return-address for context-function
; will be entered after context-function returns (LR register)
adr x1, finish
str x1, [x0, #0x98]
ret x30 ; return pointer to context-data (x0)
trampoline
stp fp, lr, [sp, #-0x10]!
mov fp, sp
blr x19
finish
; exit code is zero
mov x0, #0
; exit application
bl _exit
ENDP
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"
.text
.globl make_fcontext
@ -115,5 +111,3 @@ finish:
/* Mark that we don't need executable stack. */
.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 | | | *
* ------------------------------------------------- *
* *
*******************************************************/
.text
.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__
# include "make_i386_sysv_elf_gas.S"
# if defined __CET__
# include <cet.h>
# define SHSTK_ENABLED (__CET__ & 0x2)
# define BOOST_CONTEXT_SHADOW_STACK (SHSTK_ENABLED && SHADOW_STACK_SYSCALL)
# else
# if defined __CET__
# include <cet.h>
# define SHSTK_ENABLED (__CET__ & 0x2)
# define BOOST_CONTEXT_SHADOW_STACK (SHSTK_ENABLED && SHADOW_STACK_SYSCALL)
# else
# define _CET_ENDBR
# endif
# define _CET_ENDBR
# endif
.file "make_x86_64_sysv_elf_gas.S"
.text
.globl make_fcontext
@ -187,4 +184,3 @@ finish:
/* Mark that we don't need executable stack. */
.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